13.IO流之字符流

来源:互联网 发布:录入数据 英文 编辑:程序博客网 时间:2024/05/21 11:29

 

一.读写中文

   1.使用FileInputStream和FileOutputStream读写中文

      计算机存储任何数据都是以二进制字节形式存储, 那么使用字节流是可以读写字符的. 但是比较麻烦.

      FileInputStream只能读取字节, 如果希望读取字符, 需要人工解码

//使用FileInputStream读取中文,因为 read只能读取字节,如想读取字符,需要人工解代;

   publicstaticvoid read()throws FileNotFoundException, IOException {

      FileInputStream fis = new FileInputStream("file.txt");

      int len;

      while((len = fis.read())!=-1) {

         //将读取到的数据转成byte类型;

         byte b1 = (byte)len;

         //如果转换结果小于0;说明读到了中文;

         if(b1 < 0) {

            byte b2 = (byte)fis.read();   //再读取下一个字符,同转换成byte类型;

            System.out.print(new String(newbyte[]{b1,b2})); //将两个byte字节组成一个byte数组,再转成字符串打印出来;

         } else {

//如果读取的不是负数,直接转成字符;

            System.out.print((char)len);     

         }

      }

      fis.close();    //关流;

   }

   FileOutputStream只能写出字节, 如果希望写出字符, 需要人工编码

      publicstaticvoid write()throws IOException {

      FileOutputStream fos = new FileOutputStream("file.txt");

      fos.write("今天天气不错,".getBytes());//使用getBytes转换;

      fos.write("\r\n心情很好!".getBytes());

   fos.close();

InputStream.read()方法是读一个byte,而为什么返回一个int?而且int中全是正数.

   因为byte取值范围是-128127,这些数据在文件中都有可能存在,如果读到字节直接返回,那么无法用任何一个值表示文件末尾.

   read()方法内部,将读取到的所有数据高位补0转为了int,这样做所有负数都会变为正数,返回-1就能表示文件末尾了.

  write()方法写出数据时,会将int数据强转为byte,再写出.这样就把read()方法中补的0都去掉了,得到了文件中原有数据.

一.字符流

   1.使用FileInputStream和FileOutputStream读写中文

      计算机存储任何数据都是以二进制字节形式存储, 那么使用字节流是可以读写字符的. 但是比较麻烦.

      FileInputStream只能读取字节, 如果希望读取字符, 需要人工解码

   2.使用InputStreamReader和OutputStreamWriter读写中文

      InputStreamReader包装一个InputStream, 可以直接读取字符, 自动解码

      OutputStreamWriter包装一个OutputStream, 可以直接写出字符, 自动编码

  * 3.指定码表读写字符

      在使用InputStreamReader和OutputStreamWriter的时候, 如果希望读写非平台默认码表, 在构造函数中可以指定

      publicstaticvoid writerCode()throws UnsupportedEncodingException,

         FileNotFoundException, IOException {

      //使用非平台默认码表,写出文件,同样是在构造函数中指定码表即可;

      OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("demo.txt",true),"UTF-8");//指定UTF-8码表

      osw.write("订餐");

      osw.close();

   }

   publicstaticvoid readerCode()throws IOException {

      InputStreamReader isr = new InputStreamReader(new FileInputStream("demo.txt"),"UTF-8");//指定UTF-8码表

      int len;

      while((len = isr.read())!=-1)

         System.out.print((char)len);

      isr.close();

   }

  *4.FileReader和FileWriter

      FileReader是InputStreamReader的子类, 在读取平台默认码表的文件时, 可以使用FileReader替代InputStreamReader,因为FileReader底层自动调用父类InputStreamReader,在InputStreamReader构造函数上自动创建新的FileInputStream;

      FileWriter是OutputStreamWriter的子类, 在写出平台默认码表的文件时, 可以使用FileWriter替代OutputStreamWriter

  *5.BufferedReader和BufferedWriter

      BufferedReader可以包装一个Reader, 提供缓冲功能, 而且提供了readLine()方法可以读取一行字符

readLine方法原理:

   无论是读一行,还是读取多个字符,其实最终都是在硬盘上一个一个读取,所以最终还是read方法一个一个读取的方法.

      BufferedWriter可以包装一个Writer, 提供缓冲功能, 而且提供了newLine()方法写出系统对应的换行符号

   import java.io.*;

 

publicclass BufferedReaderDemo {

   publicstaticvoid main(String[] args)throws IOException {

      //使用bufferedReader读取文件;

      reader();

   //writer();

   }

 

   publicstaticvoid writer()throws IOException {

      BufferedWriter bw = new BufferedWriter(new FileWriter("file.txt"));

      bw.write("天气不错,努力学习");

      bw.newLine();      //换行;平台通用

      bw.write("争气,出气");

      bw.close();

   }

 

   publicstaticvoid reader()throws IOException {

      BufferedReader br = new BufferedReader(new FileReader("file.txt"));

      String line;

      while((line= br.readLine())!=null)

         System.out.println(line);

      br.close();

   }

 

}

   6.LineNumberReader

      是BufferedReader的子类, 带有缓冲功能, 可以读取一行, 并且还能统计行号

   7.包装设计模式:

装饰模式比继承要灵活。避免了继承体系臃肿。而且降低了类于类之间的关系。

装饰类因为增强已有对象,具备的功能和已有的是相同的,只不过提供了更强功能。

所以装饰类和被装饰类通常是都属于一个体系中的。

//被包装的对象;读取文件的功能就在这个类中;

      FileInputStream fis = new FileInputStream("file.txt");

 

      //包装类,使用fis读取文件的功能,添加的缓冲的功能;

      BufferedInputStream bis =new BufferedInputStream(fis);

 

      //包装类,使用了fis读取文件的功能,添加了转为字符的功能;

      InputStreamReader isr = new InputStreamReader(fis);

 

      //包装类,使用了isr读取字符的功能,添加了缓冲的功能;

      BufferedReader br  =new BufferedReader(isr);

:

interface Coder{ //程序员,必须会编程

   void code();

}

 

class Studentimplements Coder {    //普通的计算机系学生

   publicvoid code() {

      System.out.println("JavaSE");

      System.out.println("JavaWeb");

   }

}

 

class ItcastStudentimplements Coder {        //4.和被包装类实现相同的接口,或者继承相同的父类.包装类就可以和被包装类一样使用了

   private Studentstudent;

 

   public ItcastStudent(Student student) {    // 1.通过构造函数接收一个被包装的对象,用成员变量引用被包装的对象

      this.student = student;             

  

  

   publicvoid code() { // 2.声明和被包装类相同的方法

      student.code();   // 3.在方法中调用被包装对象的方法,对其增强

      System.out.println("JBPM");

      System.out.println("Hibernate");

      System.out.println("Sprint");

      System.out.println("Struts");

      System.out.println("Hadoop");

      System.out.println("JNI");

      System.out.println("OpenGL");

      System.out.println("Android");

   }

}