zoukankan      html  css  js  c++  java
  • Java IO详解(五)------包装流

    1.介绍

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

    字节缓冲流:BufferedInputStream、BufferedOutputStream

    字符缓冲流:BufferedReader、BufferedWriter

    以介质是硬盘为例,字节流和字符流的弊端
    在每一次读写的时候,都会访问硬盘。 如果读写的频率比较高的时候,其性能表现不佳。

    为了解决以上弊端,采用缓存流。

    缓存流在读取的时候,会一次性读较多的数据到缓存中,以后每一次的读取,都是在缓存中访问,直到缓存中的数据读取完毕,再到硬盘中读取。

    就好比吃饭,不用缓存就是每吃一口都到锅里去铲用缓存就是先把饭盛到碗里,碗里的吃完了,再到锅里去铲缓存流在写入数据的时候,

    会先把数据写入到缓存区,直到缓存区达到一定的量,才把这些数据,一起写入到硬盘中去按照这种操作模式,就不会像字节流,字符流那样每写一个字节都访问硬盘,从而减少了IO操作。

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

    BufferedInputStream:

    public
    class BufferedInputStream extends FilterInputStream {
    
        private static int DEFAULT_BUFFER_SIZE = 8192;

    BufferedOutputStream:

    public BufferedOutputStream(OutputStream out) {
            this(out, 8192);
        }

    3.字节缓冲输入流、字节缓冲输出流

    BufferedInputStream、BufferedOutputStream

    package stream;
    
    import java.io.*;
    
    /***
     * @ClassName: BufferedInputStreamDem
     * @Description: TODO
     * @Auther: chujiu
     * @Date: 2020/6/9
     * @version : V1.0
     */
    public class BufferedInputStreamDem {
    
        public static void main(String[] args) throws IOException {
    //字节缓冲输入流,创建文件字符流,缓存流必须建立在一个存在的流的基础上 BufferedInputStream bis = new BufferedInputStream( new FileInputStream("G:" + File.separator + "javabased" + File.separator + "JavaTest" + File.separator + "java.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(); //字节缓冲输出流,创建文件字符流,缓存流必须建立在一个存在的流的基础上 BufferedOutputStream bos = new BufferedOutputStream( new FileOutputStream("G:" + File.separator + "javabased" + File.separator + "JavaTest" + File.separator + "java.txt")); bos.write("ABCD".getBytes()); //关闭流资源 bos.close(); } }

    4.字符缓冲输入流、字符缓冲输出流

    BufferedReader、BufferedWriter

    package stream;
    
    import java.io.*;
    
    /***
     * @ClassName: BufferedReaderDemo
     * @Description: TODO
     * @Auther: chujiu
     * @Date: 2020/6/9
     * @version : V1.0
     */
    public class BufferedReaderDemo {
        public static void main(String[] args) throws IOException {
    
            //字符缓冲输入流,创建文件字符流,缓存流必须建立在一个存在的流的基础上
            BufferedReader br = new BufferedReader(
                    new FileReader("G:" + File.separator + "javabased" + File.separator + "JavaTest" + File.separator + "java.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("G:" + File.separator + "javabased" + File.separator + "JavaTest" + File.separator + "java.txt"));
    
    
            bw.write("ABCD");
    
            //关闭流资源
            bw.close();
        }
    }

    5.转换流:把字节流转换为字符流

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

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

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

    package stream;
    
    import java.io.*;
    
    /***
     * @ClassName: FileOutputStreamCopy
     * @Description: TODO
     * @Auther: chujiu
     * @Date: 2020/6/10
     * @version : V1.0
     */
    public class FileOutputStreamCopy {
        public static void main(String[] args) throws IOException {
    
            /**
             * 将 a.txt 文件 复制到 b.txt 中
             */
            //1、创建源和目标
            File srcFile = new File("G:" + File.separator + "javabased" + File.separator + "JavaTest" + File.separator + "a.txt");
            File descFile = new File("G:" + File.separator + "javabased" + File.separator + "JavaTest" + 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();
        }
    }

    6.内存流(数组流)

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

     public void close() throws IOException {
        }

    ①、字节内存流:ByteArrayOutputStream 、ByteArrayInputStream

    package stream2;
    
    import java.io.ByteArrayInputStream;
    import java.io.ByteArrayOutputStream;
    import java.io.IOException;
    
    /***
     * @ClassName: ByteArrayDemo
     * @Description: TODO
     * @Auther: chujiu
     * @Date: 2020/6/10 2:51
     * @version : V1.0
     */
    public class ByteArrayDemo {
        public static void main(String[] args) throws IOException {
    
            //字节数组输出流:程序---》内存
            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

    package stream2;
    
    import java.io.CharArrayReader;
    import java.io.CharArrayWriter;
    import java.io.IOException;
    
    /***
     * @ClassName: CharArrayDemo
     * @Description: TODO
     * @Auther: chujiu
     * @Date: 2020/6/10
     * @version : V1.0
     */
    public class CharArrayDemo {
        public static void main(String[] args) throws IOException {
    
            //字符数组输出流
            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(把数据临时存储到字符串中)

    package stream2;
    
    import java.io.IOException;
    import java.io.StringReader;
    import java.io.StringWriter;
    
    /***
     * @ClassName: StringReaderDemo
     * @Description: TODO
     * @Auther: chujiu
     * @Date: 2020/6/10
     * @version : V1.0
     */
    public class StringReaderDemo {
        public static void main(String[] args) throws IOException {
    
            //字符串输出流,底层采用 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帅锅
            }
        }
    }

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

    package stream2;
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.SequenceInputStream;
    
    /***
     * @ClassName: SequenceInputStreamDemo
     * @Description: TODO
     * @Auther: chujiu
     * @Date: 2020/6/10
     * @version : V1.0
     */
    public class SequenceInputStreamDemo {
        public static void main(String[] args) throws IOException {
    
            //定义字节输入合并流
            SequenceInputStream seinput = new SequenceInputStream(
                    new FileInputStream("G:" + File.separator + "javabased" + File.separator + "JavaTest" + File.separator + "a.txt"),
                    new FileInputStream("G:" + File.separator + "javabased" + File.separator + "JavaTest" + File.separator + "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();
        }
    }

    参考文章:https://www.cnblogs.com/ysocean/tag/Java%20IO%E8%AF%A6%E8%A7%A3%E7%B3%BB%E5%88%97/

    一辈子很短,努力的做好两件事就好;第一件事是热爱生活,好好的去爱身边的人;第二件事是努力学习,在工作中取得不一样的成绩,实现自己的价值,而不是仅仅为了赚钱。
  • 相关阅读:
    Halcon学习笔记之缺陷检测(二)
    tensorflow常用函数库
    luogu P2765 魔术球问题 (最小路径覆盖)
    luogu P2423 [HEOI2012]朋友圈 (最大团)
    poj 2226 Muddy Fields (二分图)
    匈牙利算法板子
    二分图
    AC日记——【模板】树链剖分 洛谷 P3384
    AC日记——[ZJOI2008]树的统计Count bzoj 1036
    去重排序
  • 原文地址:https://www.cnblogs.com/antao/p/13082525.html
Copyright © 2011-2022 走看看