p5 节点流和处理流

发布时间 2023-06-05 20:13:11作者: 凉白茶

节点流 和 处理流

  • 节点流和处理流一览图:

img

​ 【图片来源】http://t.csdn.cn/d52a1

一、基本介绍

  1. 节点流:节点流可以从一个特定的数据源读写数据,如FIleReader、FileWriter

  2. 处理流:处理流(也叫包装流)是“连接”在已存在的流(节点流或处理流)之上,为程序提供更为强大的读写功能,也更加灵活,如BufferedReader、BufferedWriter。使用了修饰器设计模式。就是面向对象的封装思想,消除不同数据之间的差异性,仅对外暴露接口。

二、节点流 和 处理流 的区别和联系

  1. 节点流是底层流/低级流,直接跟数据源相接。

  2. 处理流(包装流)包装结点流,即可以消除不同节点的实现差异,也可以提供更方便的方法来完成输入输出。

  3. 处理流(也叫包装流)对节点流进行包装,使用了修饰器设计模式,不会直接与数据源相连

    /**
     * @author
     * @version 1.0
     * 模拟修饰器设计模式
     */
    public class Test_ {
        public static void main(String[] args) {
            BufferedReader_ bufferedReader_ = new BufferedReader_(new FileReader_());
            bufferedReader_.readFiles(10);
    
            //希望通过BufferedReader_ 多次读取字符串
            BufferedReader_ bufferedReader_1 = new BufferedReader_(new StringReader_());
            bufferedReader_1.readStrings(5);
        }
    }
    abstract class Reader_ {
        public void readFile_(){}
        public void readString_(){}
    
        //在Reader_抽象类,使用read方法统一管理
    //    public abstract void read();
        //后面在调用时就,利于对象动态绑定机制,绑定到对应的实现子类即可。
    }
    
    // 模拟节点流
    class FileReader_ extends Reader_{
        public void readFile_(){
            System.out.println("对文件进行读取……");
        }
    //    public void read(){
    //        System.out.println("对文件进行读取……");
    //    }
    }
    
    //模拟节点流
    class StringReader_ extends Reader_{
        public void readString_(){
            System.out.println("读取字符串……");
        }
    //    public void read(){
    //        System.out.println("读取字符串……");
    //    }
    }
    
    
    //模拟处理流/包装流
    class BufferedReader_ extends Reader_{
        //注意装饰器模式中,装饰类和被装饰类(约定俗成,而非必须)继承自同一个父类。
        private Reader_ reader_;//属性是 Reader_
    
        //接收Reader_子类对象
        public BufferedReader_(Reader_ reader_) {
            this.reader_ = reader_;
        }
    
        public void readFile(){
            reader_.readFile_();
        }
    
        //让方法更灵活,多次读取文件,或者加缓冲char[]....
        public void readFiles(int num){
            for (int i = 0; i < num; i++) {
                reader_.readFile_();
            }
        }
    
        //扩展 readString,批量处理字符串数据
        public void readStrings(int num){
            for (int i = 0; i < num; i++) {
                reader_.readString_();
            }
        }
    }
    
    

三、处理流的功能主要体现在以下两个方面:

  1. 性能的提高:主要以增加缓冲的方式来提高输入和输出的效率。
  2. 操作的便捷:处理流提供了一系列便捷的方法来一次输入输出大批量的数据就,使用更加灵活方便。

四、处理流 — BufferedReader和BufferedWriter

  • BufferedReader 和 BufferedWriter属于字符流,是按照字符来读取数据的;
  • 关闭处理流,只需关闭外层流即可,关闭外层流(包装流)时会自动关闭包装的节点流;
  • BufferedReader 和 BufferedWriter 是安装字符操作,不要去操作二进制文件,可能造成文件损坏;
  1. BufferedReader

    • 构造方法摘要

      Constructor and Description
      BufferedReader(Reader in)创建使用默认大小的输入缓冲区的缓冲字符输入流。
      BufferedReader(Reader in, int sz)创建使用指定大小的输入缓冲区的缓冲字符输入流。
    • 方法摘要

      Modifier and Type Method and Description
      void close()关闭流并释放与之相关联的任何系统资源。
      Stream<String> lines()返回一个 Stream ,其元素是从这个 BufferedReader读取的行。
      void mark(int readAheadLimit)标记流中的当前位置。
      boolean markSupported()告诉这个流是否支持mark()操作。
      int read()读一个字符
      int read(char[] cbuf, int off, int len)将字符读入数组的一部分。
      String readLine()读一行文字。
      boolean ready()告诉这个流是否准备好被读取。
      void reset()将流重置为最近的标记。
      long skip(long n)跳过字符
    • 代码演示:

      import java.io.BufferedReader;
      import java.io.FileNotFoundException;
      import java.io.FileReader;
      import java.io.IOException;
      
      /**
       * @author
       * @version 1.0
       * 演示BufferedReader的使用
       */
      public class BufferedReader_ {
          public static void main(String[] args) throws IOException {
              String filePath = "e:\\a.java";
              //创建BufferedReader对象
              BufferedReader bufferedReader = new BufferedReader(new FileReader(filePath));
              //读取
              String line;//按行读取,效率高
              //1. bufferedReader.readLine() 是按行读取文件
              //2. 当返回null时,表示文件读取完毕
              while((line = bufferedReader.readLine()) != null){
                  System.out.println(line);
              }
      
              //关闭流
              //这里注意,只需关闭 BufferedReader(外层流),因为底层会自动的去关闭节点流 FileReader
              /**
               * public void close() throws IOException {
               *         synchronized (lock) {
               *             if (in == null)
               *                 return;
               *             try {
               *                 in.close();
               *             } finally {
               *                 in = null;// in 就是我们传入的 new FileReader(filePath),关闭了
               *                 cb = null;
               *             }
               *         }
               *     }
               */
              bufferedReader.close();
          }
      }
      
      
    1. BufferedWriter

      • 构造方法摘要

        Constructor and Description
        BufferedWriter(Writer out)创建使用默认大小的输出缓冲区的缓冲字符输出流。
        BufferedWriter(Writer out, int sz)创建一个新的缓冲字符输出流,使用给定大小的输出缓冲区。
      • 方法摘要

        Modifier and Type Method and Description
        void close()关闭流,先刷新。
        void flush()刷新流。
        void newLine()写一行行分隔符。
        void write(char[] cbuf, int off, int len)写入字符数组的一部分。
        void write(int c)写一个字符
        void write(String s, int off, int len)写一个字符串的一部分。
      • 代码演示:

        import java.io.BufferedWriter;
        import java.io.FileWriter;
        import java.io.IOException;
        
        public class BufferedWriter_ {
            public static void main(String[] args) throws IOException {
                String filePath = "e:\\BufferedWriter_.java";
                BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(filePath, true));
                bufferedWriter.write("hello, 你好");
                //插入一个和系统 相关的换行
                bufferedWriter.newLine();
        //        bufferedWriter.write("\r\n");
                bufferedWriter.write("hello, 你好");
                //关闭外层流即可,传入的节点流会自动关闭
                bufferedWriter.close();
        
            }
        }