47.黑马程序员-IO流缓冲区、装饰设计模式

来源:互联网 发布:淘宝优惠券入口 编辑:程序博客网 时间:2024/05/22 00:24

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

一、缓冲区
  • 概念:缓冲区的出现提高了对数据的读写效率。
  • 对应类:BufferedWriter、BufferReader。
  • 缓冲区要结合流才可以使用。缓冲区对流进行了增强。
    1.BufferedWriter缓冲区
  • 打开缓冲区:只需要将流对象最为参数传递给构造函数即可。
    • BufferedWriter bufw = new  BufferedWriter (fw) //fw为FileWriter对象。
  • 使用缓冲区:因为缓冲区也继承自Writer,可以使用Writer的方法。
    • 写入需要使用write(“内容”)
    • newLine(); //换行,在linux,windows等OS下都是换行,提高通用性。
      • //返回的时候只返回回车符之前的数据内容,并不返回回车符。所以注意:每次 line = redaLine() 读取完,write(line)后,必须加上两句:bufw.newLine();和bufw.flush(); 。 否则写到文件中的数据没有换行符。
    • 使用缓冲区记得刷新flush()。
  • 关闭缓冲区: 直接关闭bufw即可。 流对象才是具体操作数据的。关闭缓冲区其实就是关闭缓冲区中的流对象。
    • bufw.close();
    2.BufferedReader缓冲区
  • 打开缓冲区:只需要将流对象最为参数传递给构造函数即可。
    • BufferedReader bufr = new  Buffered Reader(fr) //fr为FileWriter 对象。
  • 使用缓冲区:因为缓冲区也继承自Writer,可以使用Writer的方法。使用缓冲区记得刷新
    • 读取方法redaLine();
      • //读一行。返回值类型string,为null就读完。
      • //返回的时候只返回回车符之前的数据内容,并不返回回车符。所以注意:每次 line = redaLine() 读取完,write(line)后,必须加上两句:bufw.newLine();和bufw.flush(); 。 否则写到文件中的数据没有换行符。
      • 原理:
      • 1.无论是读一行,还是获取多个字符,最终都是在硬盘上一个一个读取。
      • 2.读取到的字符存在一个数组中,当读取到\r时就先不存而是继续读取, 下一个是\n时就代表一行结束,返回这个数组。注意\r\n不会返回。
    • 读取不需要刷新。
  • 关闭缓冲区: 直接关闭bufw即可。 流对象才是具体操作数据的。关闭缓冲区其实就是关闭缓冲区中的流对象。
    • burw.close();
    3.通过缓冲区复制文件。
  • 复制一个.java文件。
    • /*通过缓冲区复制一个.java文件*/import java.io.*;class  CopyTextByBuf{public static void main(String[] args) {BufferedReader bufr = null;BufferedWriter bufw = null;try{bufr = new BufferedReader(new FileReader("c:\\buf.txt"));bufw = new BufferedWriter(new FileWriter("d:\\Copy_buf.txt"));String line = null;while ((line = bufr.readLine())!=null){bufw.write(line);bufw.flush();}}catch (IOException e){throw new RuntimeException("读写失败");}finally{try{if (bufr != null){bufr.close();}}catch (IOException e){throw new RuntimeException("读取关闭失败");}try{if (bufw != null){bufr.close();}}catch (IOException e){throw new RuntimeException("写入关闭失败");}}}}

    二、装饰设计模式
    1.概念
  • 当想要对已有对象进行功能增强时,可以定义类,将已有对象传入,给予已有的功能,并提供加强功能,那么自定义的类成为装饰类。
  • BufferedReader就属于装饰类。
    2.举例
  • MyReader //专门用于读取数据的类
    • |--MyTextReader
      • |--MyBufferTextReader
    • |--MyMediaReader
      • |--MyMediaTextReader
    • |--MyDataReader
      • |--MyDataTextReader
    • 这个类扩展性不好、臃肿。用的缓冲技术是一样的,没必要定义单独的子类,我们可以定义一个缓冲区,谁需要缓冲就传进来。
    • 那么重载构造函数行不行呢?
    • class MyBufferReader
    • {
      • MyBufferReader( MyBufferTextReader ){}
      • MyBufferReader( MyMediaTextReader ){}
      • MyBufferReader( MyDataTextReader ){}
    • }//这个类扩展性也是极差,找到其参数的共同类型,通过多态的形式,可以提高效率。
    • 装饰设计模式:
    • class MyBufferReader extends MyReader
    • {
      • MyBufferReader(  MyReader  r){}
    • }
    • 装饰模式结构
      • MyReader //专门用于读取数据的类
        • |--MyTextReader
        • |--MyMediaReader
        • |--MyDataReader
        • |--MyBufferReader
    3.与继承的区别
  • 装饰模式比继承要灵活,避免了继承体系的臃肿。从而降低了类与类之间的关系。
  • 装饰类因为增强已有的对象,具备的功能和已有的是相同的,只不过提供了更强功能。所以装饰类和被装饰类通常是一个体系中的。
  • 不要已继承为主,可以通过装饰扩展。
  • 当发现一个类的功能不够用,可以新建一个装饰类,把原来的类传入进来。
    4.装饰类继承父类
  • 例如继承Reader类,如何覆盖Reader类中的抽象方法。
    • 可以通过Reader类的子类复写,直接返回子类对象的方法就可以。
    • 例如 Reader类 的read方法是抽象方法。代码:
    • MyBufferedReader (Reader r){this.r=r;}// MyBufferedReader 是装饰类,r是被装饰的Reader类的子类。
    • public int read(char[] buff,int off, int len)
    • {
      • return r.read(buff,off,len);//这里怎么实现不知道,可以使用传进来的子类去实现。
    • }
    5.总结
  • 装饰类与“被装饰的多个类”都集成同一个父类,
  • 与它们平行,简化了继承的臃肿。

  • BufferdeReader与BufferdeWriter就是Reader类和Writer类的装饰类。
  • 继承Reader类和Writer类并且需要覆盖一些抽象方法。
原创粉丝点击