心得---字符流、缓冲流、装饰模式

若如初见. 提交于 2020-03-09 08:11:52

1.    Reader类和Writer类用来专门处理字符流。这两个类都是抽象类,从他们派生出了许多子类,增强功能、提高效率,实现各种不同要求的字符输入/输出流的处理。

     IO体系中的子类名后缀都是父类名称,而前缀都是体现子类功能的名字。字符流用于存储和检索文本。两者的使用方法与InputStream类和OutputStream类基本相同,不同的是,这两个类以Unicode字符为单位进行读写,当写入一个16 位的Unicode字符时,按字节分成两部分,先写高位字节,后写低位字节。

     对于读取或者写入流对象的构造函数,以及读写方法,还有刷新关闭功能都会抛出IOException或其子类,所以都要进行处理。

2. Reader

抽象类java.io.Reader是所有字符输入流类型的父类,其中声明了用于读取字符流的有关方法,其类层次关系为:

                               

3. Reader类中定义的方法

µ   public int read():读取一个字符,返回的是读到的那个字符。如果读到流的末尾,返回-1。

µ   public int read(char[] cbuf):将读到的字符存入指定的数组中,返回的是实际读取的字符数。如果读到流的末尾,返回-1。

µ   public abstract int read(char[]cbuf,int off,int len):将读到的字符存入数组的指定位置(off),每次最多读len个字符,返回实际读取的字符数。如果读到流的末尾,返回-1。

µ   close():读取字符其实用的是window系统的功能,使用完毕后,进行资源的释放。

4. Writer

Java.io.Writer与java.io.Reader类对应,是所有字符输出流类型的共同父类,也是一个抽象类,其中声明了用于写字符流的有关方法。

  

5. Writer类中定义的主要方法

µ   public void write(int c):将一个字符写入到流中。

µ   public void write(char[]):将数组中的字符依次写出。

µ   public abstract void write(char[]bcbuf,int off,int len):将数组中下标off开始的len个字符写出。

µ   public void write(String):将一个字符串写入到流中。

µ   public abstract void flush():刷新流,将流中的数据刷新到目的地中,流还存在。Reader类中没有该方法。

µ   public abstreact void close():关闭资源,关闭前会先调用flush,刷新流中的数据去目的地,然后流关闭。

6. FileWriter的使用

µ   该类没有特有的方法。只有自己的构造函数。

µ   该类特点:

¯   用于处理文本文件。

¯   该类中有默认的编码表,

¯   该类中有临时缓冲。

µ   构造函数

¯   public FileWriter(String filename);//调用系统资源,在指定位置,创建一个文件。注意:如果该文件已存在,将会被覆盖。

¯   public FileWriter(Stringfilename,boolean append);//当传入的boolean类型的参数值为true时,会在指定文件末尾处进行数据的续写。

7.完整的异常处理方式:例:

class Demo{

     public staticvoid main(String[] args)throws IOException{

        FileWriterfw = null;

        try{

          fw = newFileWriter("z:\\demo.txt");

          fw.write("abcdec");

          fw.flush();

          fw.write("kkkk");

     }catch(IOExceptione){

        System.out.println(e.toString());

     }finally{

        if(fw!=null)

          try{

             fw.close(); 

          }catch(IOExceptione){

             System.out.println("close:"+e.toString());

          } 

     } 

   }

}

8.当指定绝对路径时,定义目录分隔符有两种方式:

•       反斜线但是一定要写两个。\\ new FileWriter("c:\\demo.txt");(否则会默认为转义字符,第一个为转义字符)

•       斜线  /  写一个即可。 new FileWriter("c:/demo.txt");

9. FileReader的使用

•       用于读取文本文件的流对象。

•       构造函数:在读取流对象初始化的时候,必须要指定一个被读取的文件。
public FileReader(String filename);//如果该文件不存在会发生FileNotFoundException

 

注意:read方法若返回-1,则表明当前读取位置已经到达流的末尾。例如(读取文件的全部内容):int ch = 0;

while((ch=fr.read())!=-1){

       //数据处理(char)ch

}

10. 缓冲的字符流BufferedReader/BufferedWriter

µ   采用缓冲处理是为了提高效率,如果没有缓存,例如FileReader对象,每次调用read()方法进行读操作时,都会直接去文件中读取字节,转换成字符并返回,这样频繁的读取文件效率很低。

µ   缓冲的字符流的出现提高了对流的操作效率,原理就是将数组进行封装。

µ   在使用缓冲的字符流对象时,缓冲的存在是为了增强流的功能,因此在建立缓冲的字符流对象时,要先有流对象的存在。

public BufferedReader(Reader in) ;

public BufferedReader(Reader in, int sz) :创建一个使用制定大小输入缓冲区的缓冲字符输入流,sz指输入缓冲区的大小,如果sz<=0,则抛出IllegalArgumentException异常。

public BufferedWriter(Writer out) ;

public BufferedWriter(Writer out, int sz);

µ   BufferedReader的特有方法:public String readLine();//一次读一行,到行标记时,将行标记之前的字符数据作为字符串返回。当读到末尾时,返回null。

µ   BufferedWriter的特有方法:public void newLine();//写出平台相关的行分隔符来标记一行的终止。Windows平台下为’\n’。

使用缓冲的字符流时其实就是使用流对象的方法,只不过加入了数组,对数据进行了临时存储,为了提高操作数据的效率。

方法readLine()的原理:该方法用的还是与缓冲的字符流相关联的流对象的read()方法,只不过,每一次读到一个字符,先不进行具体操作,先进行临时存储,当读取到回车标记时,将临时容器中存储的数据一次性返回。

注意,它的出现是基于流并增强了流的功能。这也是一种设计模式的体现:装饰设计模式,对一组对象进行功能的增强。

11. 装饰设计模式比继承有更好的灵活性

需求:想要对数据的操作提高效率,就用到了缓冲技术。

方法:通过所学的继承特性,可以建立MediaWriter类的子类和TextWriter类的子类,在子类中重写父类的write方法即可

问题:当Writer中子类对象过多,那么为了提高每一个对象效率,每一个对象都有 一个自己的子类Buffered。虽然可以实现,但是继承体系变的很臃肿。那么是否可以对其进行优化呢?

解决方法:增加的这些子类都是在使用缓冲技术。可不可以对缓冲技术进行描述,将需要增强的对象传递给缓冲区即可。

classBufferdWriter{

     BufferedWriter(MediaWritermw){}

     BufferedWriter(TextWritermw){}

}

出现的新的问题:该类虽然完成对已有两个对象的增强。但是当有新的对象出现时,还要继续在该类中添加构造函数。这样不利于扩展和维护。

解决方法:将对这些对象父类型进行操作即可。这就是多态,提高了程序的扩展性。同时BufferedWriter中一样具体write方法,只不过是增强后的write。所以BuferedWriter也应该是Writer中的一个子类。

class BufferedWriter extends Writer{

   private Writerw;

   BufferedWriter(Writerw){

     this.w = w;

   }

}

结论:这样就会发现装饰设计模式,优化增强功能的部分。比继承要灵活很多。

装饰类和被装饰类都同属于一个父类或接口

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!