黑马程序员——java第二十一、二十二天:IO流(二)

来源:互联网 发布:什么是涉密网络 编辑:程序博客网 时间:2024/06/06 00:47

------- android培训、java培训、期待与您交流! ----------

File

File:用来将文件或文件夹封装成对象,方便对文件与文件夹的属性信息进行操作。

File对象可以作为参数传递给流的构造函数。

流对象只能操作数据信息,而File对象可以对文件或文件夹进行属性信息操作

 

创建File对象

1、             将a.txt封装成File对象,可以将已有的和未有的文件或者文件夹封装成对象。

1)、File f1=new File(“a.txt”);

2)、File f2=new File(“c:\\abc”,”a.txt”);

3)、File d=new File(“a:\\abc”);

        File f3=newFile(d,”a.txt”);

System.out.println(f1);\\打印的是路径(封装的是相对路径,打印的就是相对路径;封装的是绝对路径,打印的就是绝对路径);

 

方法:

       seperator();目录分隔符,因为”\\”不利于跨平台,所以有了目录分割符

       例子:Filef4=new File(“c:\\abc\\cc\\a.txt”);就可以写成:

              Filef4

=new File(“c:”+File.separator+”abc”+File.separator+”cc”+File.separator+”a.txt”);

 

File对象功能

File类的常见方法:

1、创建:

boolean createNewFile();

在指定位置创建文件,如果该文件已经存在,则不创建,并返回false;和输出流不一样的是输出流对象已建立就创建文件,而且文件若已经存在则会覆盖。

 

例子:

        File f=newFile(“file.txt”);

        sop(“create”+f.createNewFile());

 

static File

createTempFile(String prefix,String suffix)
在默认临时文件目录中创建一个空文件,使用给定前缀和后缀生成其名称。返回: 表示新建空文件的抽象路径名

static File

createTempFile(String prefix,String suffix,File directory)  在指定目录中创建一个新的空文件,使用给定的前缀和后缀字符串生成其名称。

 

boolean

mkdir()
创建此抽象路径名指定的目录(只能创建一级目录)。

 boolean

mkdirs()
创建此抽象路径名指定的目录,包括所有必需但不存在的父目录(也就是可以创建多级《多层》目录)。

 

2、删除:

boolean

delete()
 删除此抽象路径名表示的文件或目录。eg:f.delete()

 void

deleteOnExit()
在虚拟机终止时,请求删除此抽象路径名表示的文件或目录(出现异常时也可以删除)。

 

3、判断:

boolean

canExecute()
测试应用程序是否可以执行此抽象路径名表示的文件。

 boolean

canRead()
测试应用程序是否可以读取此抽象路径名表示的文件。

 boolean

canWrite()
测试应用程序是否可以修改此抽象路径名表示的文件。

 int

compareTo(File pathname)
按字母顺序比较两个抽象路径名。

boolean

exists()
测试此抽象路径名表示的文件或目录是否存在。

 boolean

isDirectory() (必须先判断文件夹是否存在)测试此抽象路径名表示的文件是否是一个目录。

 boolean

isFile()(必须先判断文件是否存在)测试此抽象路径名表示的文件是否是一个标准文件。

 boolean

isHidden() 测试此抽象路径名指定的文件是否是一个隐藏文件(java中有些隐藏的文件访问不了,需要先判断一下)

 boolean

isAbsolute() 测试此抽象路径名是否为绝对路径名。(文件不存在也可以判断)

 

4、获取信息:

String

getName() 返回由此抽象路径名表示的文件或目录的名称。

 String

getParent() 返回此抽象路径名父目录的路径名字符串;如果此路径名没有(封装)指定父目录,则返回 null。

 String

getPath() 将此抽象路径名转换为一个路径名字符串。(封装是什么路径获取就是什么路径)

 String

getAbsolutePath() 返回此抽象路径名的绝对路径名字符串。

 File

getAbsoluteFile() 返回此抽象路径名的绝对路径名形式。

 long

lastModified() 返回此抽象路径名表示的文件最后一次被修改的时间。

 long

length() 返回由此抽象路径名表示的文件的长度。

 boolean

renameTo(File dest) 重新命名此抽象路径名表示的文件。

例子:

File f1=new File(“C:\\Test.java”);

File f2=new File(“d:\\demo.txt”);

f1.renameTo(f2);这样重命名后还会移动文件,因为路径不同。

File对象功能—文件列表

static File[]

listRoots() 列出可用的文件系统根。

 String[]

list() 返回一个字符串数组,这些字符串指定此抽象路径名表示的当前目录中的文件和目录(包括隐藏的)(封装的必须是目录)。(目录必须存在)

 File[]

listFiles() 返回一个抽象路径名数组,这些路径名表示此抽象路径名表示的当前目录中的文件。

 String[]

list(FilenameFilter filter) 返回一个字符串数组,这些字符串指定此抽象路径名表示的目录中满足指定过滤器的文件和目录。(文件名过滤)

 

文件名过滤器例子:

import java.io.*;public class FileDemo {   public static void main(String[] args) {      listDemo();   }   public static void listDemo(){      File f=new File("C:\\");      String[] arr=f.list(new FilenameFilter(){         public boolean accept(File dir,String name){            return name.endsWith(".txt");         }      });      for(String s:arr){         System.out.println(s);      }   }}


列出目录下所有的目录及文件—递归

因为目录中还有目录,只要使用同一个列出目录功能的函数完成即可。

在列出过程中出现的还是目录的话,还可以再次调用本功能。

也就是函数自身调用自身。

这种表现形式,或者编程手法,称为递归。

 

递归要注意:

1,限定条件。

2,要注意递归的次数。尽量避免内存溢出。

 

例子:

       public static void shouDir(File dri){

              System.out.println(dri);

              File[]files=dri.listFiles();

              for(intx=0;x<files.length;x++){

                     if(dri.isDirectory())

                            showDir(files[x]);

                     else

                            System.out.println(file[x]);

}

       }

 

改善层级:

class FileDemo3{       publicstatic void main(String[] args)       {              Filedir = new File("d:\\testdir");              showDir(dir,0);       }       publicstatic String getLevel(int level)       {              StringBuildersb = new StringBuilder();              sb.append("|--");              for(intx=0; x<level; x++)              {                     sb.insert(0,"|  ");               }              returnsb.toString();       }       publicstatic void showDir(File dir,int level)       {              System.out.println(getLevel(level)+dir.getName());              level++;              File[]files = dir.listFiles();              for(intx=0; x<files.length; x++)              {                     if(files[x].isDirectory())                            showDir(files[x],level);                     else                            System.out.println(getLevel(level)+files[x]);              }       }


 删除带内容的目录

删除一个带内容的目录。

删除原理:

在window中,删除目录从里面往外删除的。

 

既然是从里往外删除。就需要用到递归。

 

import java.io.*;class RemoveDir{       publicstatic void main(String[] args)       {              Filedir = new File("d:\\testdir");              removeDir(dir);       }       publicstatic void removeDir(File dir)       {              File[]files = dir.listFiles();              for(intx=0; x<files.length; x++)              {                     if(files[x].isDirectory())                            removeDir(files[x]);                     else                            System.out.println(files[x].toString()+":-file-:"+files[x].delete());              }              System.out.println(dir+"::dir::"+dir.delete());       }}


 

创建java文件列表

将一个指定目录下的java文件的绝对路径,存储到一个文本文件中。

建立一个java文件列表文件。

 

思路:

1,对指定的目录进行递归。

2,获取递归过程所以的java文件的路径。

3,将这些路径存储到集合中。

4,将集合中的数据写入到一个文件中。

 

*/

import java.io.*;import java.util.*;class JavaFileList{       publicstatic void main(String[] args) throws IOException       {              Filedir = new File("d:\\java1223");              List<File>list = new ArrayList<File>();              fileToList(dir,list);              Filefile = new File(dir,"javalist.txt");              writeToFile(list,file.toString());                    }       publicstatic void fileToList(File dir,List<File> list)       {              File[]files = dir.listFiles();              for(Filefile : files)              {                     if(file.isDirectory())                            fileToList(file,list);                     else                     {                            if(file.getName().endsWith(".java"))                                   list.add(file);                     }              }       }       publicstatic void writeToFile(List<File> list,String javaListFile)throwsIOException       {              BufferedWriterbufw =  null;              try              {                     bufw= new BufferedWriter(new FileWriter(javaListFile));                                         for(Filef : list)                     {                            Stringpath = f.getAbsolutePath();                            bufw.write(path);                            bufw.newLine();                            bufw.flush();                     }              }              catch(IOException e)              {                     throwe;              }              finally              {                     try                     {                            if(bufw!=null)                                   bufw.close();                     }                     catch(IOException e)                     {                            throwe;                     }              }       }}


Properties概述

Properties是hashtable的子类,有着map集合的特性——存储的键值对都是字符串。

Properties是集合和IO流相结合的集合容器。

该对象特点:可以用于键值对配置的文件,那么在加载数据时需要数据有固定格式:键=值。

 

方法:

 void

load(InputStream inStream)  从输入流中读取属性列表(键和元素对)(可以将流中的数据加载到集合)。

 void

store(Writer writer,String comments) 以适合使用load(Reader) 方法的格式,将此Properties 表中的属性列表(键和元素对)写入输出字符。

以适合使用 load(InputStream) 方法加载到 Properties 表中的格式,将此 Properties 表中的属性列表(键和元素对)写入输出流。

 void

list(PrintStream out)
          将属性列表输出到指定的输出流。

Properties存取

 Set<String>

stringPropertyNames()
          返回此属性列表中的键集,其中该键及其对应值是字符串,如果在主属性列表中未找到同名的键,则还包括默认属性列表中不同的键。

 

import java.io.*;import java.util.*; public class PropertiesDemo{       publicstatic void main(String[] args) throws IOException       {              //method_1();              loadDemo();       }       //store(Writerwriter, String comments)和void load(InputStream inStream)。用法       publicstatic void loadDemo()throws IOException       {              Propertiesprop = new Properties();              FileInputStreamfis = new FileInputStream("info.txt");              //将fis流中的数据加载进prop集合。              prop.load(fis);              prop.setProperty("wangwu","39");              FileOutputStreamfos = new FileOutputStream("info.txt");                         prop.store(fos,"haha");              //将属性列表输出到指定的输出流。              prop.list(System.out);              fos.close();              fis.close();       }       //演示,如何将流中的数据存储到集合中。       //想要将info.txt中键值数据存到集合中进行操作。       /*              1,用一个流和info.txt文件关联。              2,读取一行数据,将该行数据用"="进行切割。              3,等号左边作为键,右边作为值。存入到Properties集合中即可。        */       //load原理       publicstatic void method_1()throws IOException       {              BufferedReaderbufr = new BufferedReader(new FileReader("info.txt"));              Stringline = null;              Propertiesprop = new Properties();              while((line=bufr.readLine())!=null)              {                     String[]arr = line.split("=");                     ///System.out.println(arr[0]+"...."+arr[1]);                     prop.setProperty(arr[0],arr[1]);              }              bufr.close();              System.out.println(prop);       } //    设置和获取元素。       publicstatic void setAndGet()       {              Propertiesprop = new Properties();               prop.setProperty("zhangsan","30");              prop.setProperty("lisi","39");              Stringvalue = prop.getProperty("lisi");              prop.setProperty("lisi",89+"");              Set<String>names = prop.stringPropertyNames();              for(Strings : names)              {                     System.out.println(s+":"+prop.getProperty(s));              }       }}


      限制程序运行次数

用于记录应用程序运行次数。

如果使用次数已到,那么给出注册提示。

 

很容易想到的是:计数器。

可是该计数器定义在程序中,随着程序的运行而在内存中存在,并进行自增。

可是随着该应用程序的退出,该计数器也在内存中消失了。

 

下一次在启动该程序,又重新开始从0计数。

这样不是我们想要的。

 

程序即使结束,该计数器的值也存在。

下次程序启动在会先加载该计数器的值并加1后在重新存储起来。

 

所以要建立一个配置文件。用于记录该软件的使用次数。

 

该配置文件使用键值对的形式。

这样便于阅读数据,并操作数据。

 

键值对数据是map集合。

数据是以文件形式存储,使用io技术。

那么map+io -->properties.

 

配置文件可以实现应用程序数据的共享。

 

*/

import java.io.*;import java.util.*;class RunCount{       publicstatic void main(String[] args) throws IOException       {              Propertiesprop = new Properties();              Filefile = new File("count.ini");              if(!file.exists())                     file.createNewFile();              FileInputStreamfis = new FileInputStream(file);              prop.load(fis);              intcount = 0;              Stringvalue = prop.getProperty("time");              if(value!=null)              {                     count= Integer.parseInt(value);                     if(count>=5)                     {                            System.out.println("您好,使用次数已到,拿钱!");                            return;                     }              }              count++;              prop.setProperty("time",count+"");              FileOutputStreamfos = new FileOutputStream(file);              prop.store(fos,"");              fos.close();              fis.close();                    }}


 

PrintWriter

import java.io.*;import java.util.*; public class PrintStream {   public static void main(String[] args)throws IOException {      BufferedReader bufr=new BufferedReader(newInputStreamReader(System.in));      PrintWriter out=new PrintWriter(new FileWriter("a.txt"),true);//true说明可以自动刷新      String line=null;      while((line=bufr.readLine())!=null){         if("over".equals(line))            break;         out.println(line);//有标记才可以自动刷新,此处的ln就是标记。      }      out.close();      bufr.close();   }}


合并流SequenceInputStream

序列流:SequenceInputStream:

功能:对多个流合并,表示其他流的逻辑串联。他从输入流的有序集合开始,并从第一个输入流开始读取,直到到达文件末尾,接着从第二个输入流读取,依次类推,直到到达包含的最后一个输入流的文件未出为止。

构造函数

SequenceInputStream(Enumeration<? extendsInputStream> e)
          通过记住参数来初始化新创建的 SequenceInputStream,该参数必须是生成运行时类型为 InputStream 对象的Enumeration 型参数。

SequenceInputStream(InputStream s1,InputStream s2)
          通过记住这两个参数来初始化新创建的 SequenceInputStream(将按顺序读取这两个参数,先读取 s1,然后读取 s2),以提供从此 SequenceInputStream 读取的字节

import java.io.*;import java.util.*;public class SequenceInputStreamDemo {    public static void main(String[] args) throws IOException {      Vector<InputStream> v=newVector<InputStream>();      v.add(new FileInputStream("E:\\1.txt"));      v.add(new FileInputStream("E:\\2.txt"));      v.add(new FileInputStream("E:\\3.txt"));      Enumeration<InputStream> et=v.elements();      SequenceInputStream sis=newSequenceInputStream(et);      BufferedWriter bufw=new BufferedWriter(newOutputStreamWriter(new FileOutputStream("E:\\4.txt")));           int len=0;      while((len=sis.read())!=-1){         bufw.write(len);         bufw.flush();      }      bufw.close();      sis.close();   }}


切割文件

切割后的分文件的后缀名通常是.part,或者自己定义.suipian

 

import java.io.*;import java.util.*; class SplitFile{       publicstatic void main(String[] args) throws IOException       {              //splitFile();              merge();       }       publicstatic void merge()throws IOException       {              ArrayList<FileInputStream>al = new ArrayList<FileInputStream>();、              for(intx=1; x<=3; x++)              {                     al.add(newFileInputStream("c:\\splitfiles\\"+x+".part"));              }              finalIterator<FileInputStream> it = al.iterator();              Enumeration<FileInputStream>en = new Enumeration<FileInputStream>()              {                     publicboolean hasMoreElements()                     {                            returnit.hasNext();                     }                     publicFileInputStream nextElement()                     {                            returnit.next();                     }              };              SequenceInputStreamsis = new SequenceInputStream(en);              FileOutputStreamfos = new FileOutputStream("c:\\splitfiles\\0.bmp");              byte[]buf = new byte[1024];              intlen = 0;              while((len=sis.read(buf))!=-1)              {                     fos.write(buf,0,len);              }              fos.close();              sis.close();       }       publicstatic void splitFile()throws IOException       {              FileInputStreamfis =  newFileInputStream("c:\\1.bmp");              FileOutputStreamfos = null;              byte[]buf = new byte[1024*1024];              intlen = 0;              intcount = 1;              while((len=fis.read(buf))!=-1)              {                     fos= newFileOutputStream("c:\\splitfiles\\"+(count++)+".part");                     fos.write(buf,0,len);                     fos.close();              }              fis.close();       }}


对象的序列化

用于直接操作对象:ObjectInputStream与ObjectOutputStream

注意:被操作的对象需要实现Serializable(标记接口)。

标记接口:没有方法的接口为标记接口Serializable就为标记接口。

 

ObjectOutputStream方法:write(int val):因为是字节输出流所以保留的是最低八位。

writeInt(int val):保留为int类型。

writeLong(long val):保留的是64位二进制的长整形。

可以通过ObjectOutputStream把一个类的对象(包括这个对象的属性)写进文件是持久化,在写的过程中对这个像会有系统通过给这个类一个固定UID号作为标记,当类中内容语句改变UID号也会改变,ObjectInputStream就不能从文件中拿出那个已经吃就化的对象。如果想要在改变后也能拿出使用持久化的对象,可以给这个类手动固定一个UID号,使系统不用自动分配UID就可以了。

语句——

public static final long serialVersionUID=42L;

 

注意:用ObjectOutputStream序列化的对象中能用ObjectInputStream类的方法读入。

       如果ObjectOutputStream在文件中序列化了对个对象,则用ObjectInputStream的方法readObject()一次只能读取一个对象。

 

例子:

//用于操作对象的类(是对象持久化,和读出)。

import java.io.*;class ObjectStreamDemo{       publicstatic void main(String[] args) throws Exception       {              //writeObj();              readObj();       }//读取序列化对象       publicstatic void readObj()throws Exception       {              ObjectInputStreamois = new ObjectInputStream(new FileInputStream("obj.txt"));              Personp = (Person)ois.readObject();              System.out.println(p);              ois.close();       }//(写入)序列化对象       publicstatic void writeObj()throws IOException       {              ObjectOutputStreamoos =                     newObjectOutputStream(new FileOutputStream("obj.txt"));              oos.writeObject(newPerson("lisi0",399,"kr"));              oos.close();       }}//被序列化的对象类: import java.io.*;class Person implements Serializable{       publicstatic final long serialVersionUID = 42L;       privateString name;       transientint age;       staticString country = "cn";       Person(Stringname,int age,String country)       {              this.name= name;              this.age= age;              this.country= country;       }       publicString toString()       {              returnname+":"+age+":"+country;       }}


管道流

PipedInputStream与PipedOutputStream输入输出可以直接进行连接,结合线程使用。

 

package iostream; import java.io.*;public class PipedStreamDemo {    public static void main(String[] args) throws IOException{      PipedInputStream in=new PipedInputStream();      PipedOutputStream out=new PipedOutputStream();      in.connect(out);      Read r=new Read(in);      Write w=new Write(out);      new Thread(r).start();;      new Thread(w).start();   }}class Read implements Runnable {   private PipedInputStream in;   public Read(PipedInputStream in) {      this.in=in;   }    @Override   public void run() {      try{         byte[] buf=new byte[1024];         System.out.println("读取前。。。没有数据赌赛");         int len=in.read(buf);         System.out.println("读到数据。。组赛结束");         String s=new String(buf,0,len);         System.out.println(s);              }catch(IOException e){         throw new RuntimeException("管道读取流失败");      }finally{         try{            if(in!=null)                in.close();         }catch(IOException e){            throw new RuntimeException();         }      }   }}class Write implements Runnable {   PipedOutputStream out =null;   public Write(PipedOutputStream out) {      this.out = out;   }   public void run() {      try{         System.out.println("开始写入数据,等待6秒");         Thread.sleep(6000);         out.write("pipedlaila".getBytes());              }catch(Exception e){         throw new RuntimeException("管道写入流失败");      }finally{         try{            if(out!=null)                out.close();         }catch(IOException e){            throw new RuntimeException();         }      }    }}


RandomAccessFile

RandomAccessFile:随机访问文件,自身具备读写方法。

通过skipBytes(int x),seek(int x)来达到随机访问。

1、此类直接继承Object,不是IO体系中子类,但是IO包成员,因为有读和写。

2、此类实例支持对随机访问文件的读取和写入。

3、该文件指针可以通过getFilePointer方法读取,并通过seek方法设置。

4、内部封装了一个byte[]数组,可以通过getFilePointe()获取指针位置,同时可以通过seek()改变指针位置。

 

其实完成读写的原理就是内部封装了字节输入流和输出流,通过构造函数可以看出该类智能操作文件,而且操作文件还有模式(r,rw,rws,rwd);

调整指针位置:seek(8);指针指向角标为8的数组元素上(如果位置上有元素,写入时会覆盖原有元素)。

踏过指定字节数:skipBytes(8);跳过8个字节,能往下跳,不能往回跳。

 

如果模式为rw

       该对象的构造函数要操作的文件不存在,会自动创建。如果存在不会覆盖。

如果模式为r

       不会创建文件,会去读取一个已经存在文件,如果该文件不存在,则会出现异常。

 

class RandomAccessFileDemo{       publicstatic void main(String[] args) throws IOException       {              //writeFile_2();              //readFile();              //System.out.println(Integer.toBinaryString(258));       }       publicstatic void readFile()throws IOException       {              RandomAccessFileraf = new RandomAccessFile("ran.txt","r");                           //调整对象中指针。              //raf.seek(8*1);              //跳过指定的字节数              raf.skipBytes(8);              byte[]buf = new byte[4];              raf.read(buf);              Stringname = new String(buf);              intage = raf.readInt();              System.out.println("name="+name);              System.out.println("age="+age);              raf.close();       }       publicstatic void writeFile_2()throws IOException       {              RandomAccessFileraf = new RandomAccessFile("ran.txt","rw");              raf.seek(8*0);              raf.write("周期".getBytes());              raf.writeInt(103);              raf.close();       }       publicstatic void writeFile()throws IOException       {              RandomAccessFileraf = new RandomAccessFile("ran.txt","rw");              raf.write("李四".getBytes());              raf.writeInt(97);              raf.write("王五".getBytes());              raf.writeInt(99);              raf.close();       }}


操作基本数据类型的流对象DataStream

DataInputStream   和DataOutputStreamDataOutputStream

 

DataOutputStream的方法writeUTF(“”);写入的数据中能用DataInputStream的方法readUTF()读取。

 

import java.io.*;class DataStreamDemo{       publicstatic void main(String[] args) throws IOException       {              //writeData();              //readData();              //writeUTFDemo();//           OutputStreamWriterosw = new OutputStreamWriter(newFileOutputStream("gbk.txt"),"gbk");//           osw.write("你好");//           osw.close();//           readUTFDemo();       }       publicstatic void readUTFDemo()throws IOException       {              DataInputStreamdis = new DataInputStream(new FileInputStream("utf.txt"));              Strings = dis.readUTF();              System.out.println(s);              dis.close();       }       publicstatic void writeUTFDemo()throws IOException       {              DataOutputStreamdos = new DataOutputStream(new FileOutputStream("utfdate.txt"));              dos.writeUTF("你好");               dos.close();       }       publicstatic void readData()throws IOException       {              DataInputStreamdis = new DataInputStream(new FileInputStream("data.txt"));              intnum = dis.readInt();              booleanb = dis.readBoolean();              doubled = dis.readDouble();              System.out.println("num="+num);              System.out.println("b="+b);              System.out.println("d="+d);              dis.close();       }       publicstatic void writeData()throws IOException       {              DataOutputStreamdos = new DataOutputStream(new FileOutputStream("data.txt"));              dos.writeInt(234);              dos.writeBoolean(true);              dos.writeDouble(9887.543);              dos.close();              ObjectOutputStreamoos = null;              oos.writeObject(newO());                    }}


ByteArrayStream操作字节数组

ByteArrayInputStream与ByteArrayOutputStream

这两个类的特点是:没有调用底层,所以不用关流。

ByteArrayOutputStream中封装的数组缓冲区是可以自动增长的。

                     在构造的时候不用定义数据目的,因为该对象中已经在内部封装了可变长度的字节数组。

 

ByteArrayInputStream:在构造的时候需要接收数据源,而且数据源是一个字节数组。

 

在流操作规律讲解时:

 

源设备,

       键盘 System.in,硬盘FileStream,内存 ArrayStream。

目的设备:

       控制台System.out,硬盘FileStream,内存 ArrayStream。

 

方法writeTo(OutputStream os);//写入到流中

 

用流的思想去操作数组:

2、             操作字符数组:charArrayReader与charArrayWriter

3、             操作字符串:StringReader与StringWriter

 

例子:操作字节数组

 

import java.io.*;class ByteArrayStream{       publicstatic void main(String[] args)       {              //数据源。              ByteArrayInputStreambis = new ByteArrayInputStream("ABCDEFD".getBytes());              //数据目的              ByteArrayOutputStreambos = new ByteArrayOutputStream();              intby = 0;              while((by=bis.read())!=-1)              {                     bos.write(by);              }              System.out.println(bos.size());              System.out.println(bos.toString());       //    bos.writeTo(newFileOutputStream("a.txt"));       }}


转换流的字符编码

 

ASCII:美国标准信息交换码。用一个字节的7位可以表示。

l ISO8859-1:拉丁码表。欧洲码表用一个字节的8位表示。

l GB2312:中国的中文编码表。

l GBK:中国的中文编码表升级,融合了更多的中文文字符号。

l Unicode:国际标准码,融合了多种文字。所有文字都用两个字节来表示,Java语言使用的就是unicode

l UTF-8:最多用三个字节来表示一个字符。

字符编码

编码:字符串变成字节:

String——>byte[];(string.getBytes();)

String——>byte[];(string.getBytes(charsetName);)

 

解码:字节数组变成字符串:

byte[]——>String;(newString(byte[] b))

byte[]——>String;(newString(byte[] b,charsetName))

 

如果两个编码表都识别中文,用一个编码表编码另一个编码表解码就会出错。

如果一个编码表(表1)不识别,中文另一个(表2)识别中文,表1编码表编码,表2编码表解码,再用表2编码表编码,然后用表1编码编码表解码,会找到源数据。

import java.util.*;class EncodeDemo{       publicstatic void main(String[] args)throws Exception       {              Strings = "哈哈";              byte[] b1 = s.getBytes("GBK");              System.out.println(Arrays.toString(b1));              Strings1 = new String(b1,"utf-8");              System.out.println("s1="+s1);              //对s1进行iso8859-1编码。              byte[]b2 = s1.getBytes("utf-8");              System.out.println(Arrays.toString(b2));              Strings2 = new String(b2,"gbk");              System.out.println("s2="+s2);                    }}


字符编码—“联通”

class EncodeDemo2{       publicstatic void main(String[] args) throws Exception       {              Strings = "联通";              byte[] by = s.getBytes("gbk");              for(byteb : by)              {                     System.out.println(Integer.toBinaryString(b&255));              }              System.out.println("HelloWorld!");       }}


因为“联通”俩字用GBK编码的二进制编码和Utf-8编码表的格式一样,所以就识别查表utf-8编码表去解析这个二进制了。

 

import java.io.*;class EncodeStream{       publicstatic void main(String[] args) throws IOException       {                     //writeText();                     readText();       }       publicstatic void readText()throws IOException       {              InputStreamReaderisr = new InputStreamReader(new FileInputStream("utf.txt"),"gbk");              char[]buf = new char[10];              intlen = isr.read(buf);              Stringstr = new String(buf,0,len);              System.out.println(str);              isr.close();       }       publicstatic void writeText()throws IOException       {              OutputStreamWriterosw = new OutputStreamWriter(newFileOutputStream("utf.txt"),"UTF-8");              osw.write("你好");              osw.close();       }}

------- android培训、java培训、期待与您交流! ----------详细请查看:http://edu.csdn.net