zoukankan      html  css  js  c++  java
  • 五、包装流

    根据功能分为节点流和包装流(处理流)

        节点流:可以从或向一个特定的地方(节点)读写数据。如FileReader.

        处理流:是对一个已存在的流的连接和封装,通过所封装的流的功能调用实现数据读写。如BufferedReader.处理流的构造方法总是要带一个其他的流对象做参数。一个流对象经过其他流的多次包装,称为流的链接。

    1、前面讲的字符输入输出流,字节输入输出流都是字节流。那么什么是包装流呢?

      ①、包装流隐藏了底层节点流的差异,并对外提供了更方便的输入输出功能,让我们只关心这个高级流的操作

      ②、使用包装流包装了节点流,程序直接操作包装流,而底层还是节点流和IO设备操作

      ③、关闭包装流的时候,只需要关闭包装流即可

    2、缓冲流

      

      缓冲流:是一个包装流,目的是缓存作用,加快读取和写入数据的速度。

      字节缓冲流:BufferedInputStream、BufferedOutputStream

      字符缓冲流:BufferedReader、BufferedWriter

    案情回放:我们在将字符输入输出流、字节输入输出流的时候,读取操作,通常都会定义一个字节或字符数组,将读取/写入的数据先存放到这个数组里面,然后在取数组里面的数据。这比我们一个一个的读取/写入数据要快很多,而这也就是缓冲流的由来。只不过缓冲流里面定义了一个 数组用来存储我们读取/写入的数据,当内部定义的数组满了(注意:我们操作的时候外部还是会定义一个小的数组,小数组放入到内部数组中),就会进行下一步操作。 

          

    下面是没有用缓冲流的操作:   

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    //1、创建目标对象,输入流表示那个文件的数据保存到程序中。不写盘符,默认该文件是在该项目的根目录下
                //a.txt 保存的文件内容为:AAaBCDEF
            File target = new File("io"+File.separator+"a.txt");
            //2、创建输入流对象
            InputStream in = new FileInputStream(target);
            //3、具体的 IO 操作(读取 a.txt 文件中的数据到程序中)
                /**
                 * 注意:读取文件中的数据,读到最后没有数据时,返回-1
                 *  int read():读取一个字节,返回读取的字节
                 *  int read(byte[] b):读取多个字节,并保存到数组 b 中,从数组 b 的索引为 0 的位置开始存储,返回读取了几个字节
                 *  int read(byte[] b,int off,int len):读取多个字节,并存储到数组 b 中,从数组b 的索引为 0 的位置开始,长度为len个字节
                 */
            //int read():读取一个字节,返回读取的字节
            int data1 = in.read();//获取 a.txt 文件中的数据的第一个字节
            System.out.println((char)data1); //A
            //int read(byte[] b):读取多个字节保存到数组b 中
            byte[] buffer  = new byte[10];//这里我们定义了一个 长度为 10 的字节数组,用来存储读取的数据
            in.read(buffer);//获取 a.txt 文件中的前10 个字节,并存储到 buffer 数组中
            System.out.println(Arrays.toString(buffer)); //[65, 97, 66, 67, 68, 69, 70, 0, 0, 0]
            System.out.println(new String(buffer)); //AaBCDEF[][][]
             
            //int read(byte[] b,int off,int len):读取多个字节,并存储到数组 b 中,从索引 off 开始到 len
            in.read(buffer, 03);
            System.out.println(Arrays.toString(buffer)); //[65, 97, 66, 0, 0, 0, 0, 0, 0, 0]
            System.out.println(new String(buffer)); //AaB[][][][][][][]
            //4、关闭流资源
            in.close();

      我们查看 缓冲流的 JDK 底层源码,可以看到,程序中定义了这样的 缓存数组,大小为 8192

      BufferedInputStream:

            

      BufferedOutputStream:

          

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    //字节缓冲输入流
            BufferedInputStream bis = new BufferedInputStream(
                    new FileInputStream("io"+File.separator+"a.txt"));
            //定义一个字节数组,用来存储数据
            byte[] buffer = new byte[1024];
            int len = -1;//定义一个整数,表示读取的字节数
            while((len=bis.read(buffer))!=-1){
                System.out.println(new String(buffer,0,len));
            }
            //关闭流资源
            bis.close();<br><br>
             
            //字节缓冲输出流
            BufferedOutputStream bos = new BufferedOutputStream(
                    new FileOutputStream("io"+File.separator+"a.txt"));
            bos.write("ABCD".getBytes());
            bos.close();
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    //字符缓冲输入流
            BufferedReader br = new BufferedReader(
                    new FileReader("io"+File.separator+"a.txt"));
            char[] buffer = new char[10];
            int len = -1;
            while((len=br.read(buffer))!=-1){
                System.out.println(new String(buffer,0,len));
            }
            br.close();
             
            //字符缓冲输出流
            BufferedWriter bw = new BufferedWriter(
                    new FileWriter("io"+File.separator+"a.txt"));
            bw.write("ABCD");
            bw.close();

      

     3、转换流:把字节流转换为字符流

      InputStreamReader:把字节输入流转换为字符输入流

      OutputStreamWriter:把字节输出流转换为字符输出流

       

     用转换流进行文件的复制:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    /**
             * 将 a.txt 文件 复制到 b.txt 中
             */
            //1、创建源和目标
            File srcFile = new File("io"+File.separator+"a.txt");
            File descFile = new File("io"+File.separator+"b.txt");
            //2、创建字节输入输出流对象
            InputStream in = new FileInputStream(srcFile);
            OutputStream out = new FileOutputStream(descFile);
            //3、创建转换输入输出对象
            Reader rd = new InputStreamReader(in);
            Writer wt = new OutputStreamWriter(out);
            //3、读取和写入操作
            char[] buffer = new char[10];//创建一个容量为 10 的字符数组,存储已经读取的数据
            int len = -1;//表示已经读取了多少个字符,如果是 -1,表示已经读取到文件的末尾
            while((len=rd.read(buffer))!=-1){
                wt.write(buffer, 0, len);
            }
            //4、关闭流资源
            rd.close();
            wt.close();

      

     4、内存流(数组流):

      把数据先临时存在数组中,也就是内存中。所以关闭 内存流是无效的,关闭后还是可以调用这个类的方法。底层源码的 close()是一个空方法

            

      ①、字节内存流:ByteArrayOutputStream 、ByteArrayInputStream

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    //字节数组输出流:程序---》内存
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            //将数据写入到内存中
            bos.write("ABCD".getBytes());
            //创建一个新分配的字节数组。 其大小是此输出流的当前大小,缓冲区的有效内容已被复制到其中。
            byte[] temp = bos.toByteArray();
            System.out.println(new String(temp,0,temp.length));
             
            byte[] buffer = new byte[10];
            ///字节数组输入流:内存---》程序
            ByteArrayInputStream bis = new ByteArrayInputStream(temp);
            int len = -1;
            while((len=bis.read(buffer))!=-1){
                System.out.println(new String(buffer,0,len));
            }
             
            //这里不写也没事,因为源码中的 close()是一个空的方法体
            bos.close();
            bis.close();

      

      ②、字符内存流:CharArrayReader、CharArrayWriter

      

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    //字符数组输出流
            CharArrayWriter caw = new CharArrayWriter();
            caw.write("ABCD");
            //返回内存数据的副本
            char[] temp = caw.toCharArray();
            System.out.println(new String(temp));
             
            //字符数组输入流
            CharArrayReader car = new CharArrayReader(temp);
            char[] buffer = new char[10];
            int len = -1;
            while((len=car.read(buffer))!=-1){
                System.out.println(new String(buffer,0,len));
            }

      

      ③、字符串流:StringReader,StringWriter(把数据临时存储到字符串中)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    //字符串输出流,底层采用 StringBuffer 进行拼接
            StringWriter sw = new StringWriter();
            sw.write("ABCD");
            sw.write("帅锅");
            System.out.println(sw.toString());//ABCD帅锅
     
            //字符串输入流
            StringReader sr = new StringReader(sw.toString());
            char[] buffer = new char[10];
            int len = -1;
            while((len=sr.read(buffer))!=-1){
                System.out.println(new String(buffer,0,len));//ABCD帅锅
            }

      

    5、合并流:把多个输入流合并为一个流,也叫顺序流,因为在读取的时候是先读第一个,读完了在读下面一个流。

     

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    //定义字节输入合并流
            SequenceInputStream seinput = new SequenceInputStream(
                    new FileInputStream("io/a.txt"), new FileInputStream("io/b.txt"));
            byte[] buffer = new byte[10];
            int len = -1;
            while((len=seinput.read(buffer))!=-1){
                System.out.println(new String(buffer,0,len));
            }
             
            seinput.close();

      

  • 相关阅读:
    使用 ASP.NET Core MVC 创建 Web API(五)
    使用 ASP.NET Core MVC 创建 Web API(四)
    使用 ASP.NET Core MVC 创建 Web API(三)
    使用 ASP.NET Core MVC 创建 Web API(二)
    使用 ASP.NET Core MVC 创建 Web API(一)
    学习ASP.NET Core Razor 编程系列十九——分页
    学习ASP.NET Core Razor 编程系列十八——并发解决方案
    一个屌丝程序猿的人生(九十八)
    一个屌丝程序猿的人生(九十七)
    一个屌丝程序猿的人生(九十五)
  • 原文地址:https://www.cnblogs.com/zhoanghua/p/9292126.html
Copyright © 2011-2022 走看看