zoukankan      html  css  js  c++  java
  • Java IO流之缓冲流(深入浅出学习)

    缓冲流概述

    缓冲流,也叫高效流。能够高效读写缓冲流,能够转换编码的转换流,能够持久化存储对象的序列化对象等等。它是四个基本File流的增强,所以也是4个流,按照数据类型分类。

    • 字节缓冲流:BufferedInputStream,BufferedOutputStream
    • 字符缓冲流:BufferedReader,BufferedWriter

    缓冲流的基本原理,是在创建流对象时,会创建一个内置的默认大小的缓冲区数组,通过缓冲区读写,减少系统IO读取次数,从而提高读写的效率。

    字节缓冲流

    构造方法

    BufferedInputStream(InputStream in)
    BufferedInputStream(InputStream in, int size)
    // 创建一个新的字节缓冲输入流
    
    BufferedOutputStream(OutputStream out) // 将数据写入指定的底层输出流
    BufferedOutputStream(OutputStream out, int size) // 将具有指定缓冲区大小的数据写入指定的底层输出流
    // 创建一个新的字节缓冲输出流
    参数:
    InputStream in:字节输入流
    OutputStream out:字节输出流
    int size:缓冲区大小,不写的话,默认

    BufferedOutputStream —— 字节缓冲输出流

    举例:把数据写入到文件中

    使用步骤:

    1.创建FileOutputStream对象,构造方法中绑定要输出的目的地。
    2.创建BufferedOutputStream对象,构造方法中传递FileOutputStream对象,提高FileOutputStream对象效率。
    3.使用BufferedOutputStream对象中的方法write,把数据写入到内部冲区中。
    4.使用BufferedOutputStream对象中的方法flush,把内部冲区中的数据,刷新到文件中。
    5.释放资源(会先调用flush方法刷新数据,第4步可以省略)。
    import java.io.BufferedOutputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    
    public class DemoBufferedOutputStream {
        public static void main(String[] args) throws IOException {
            method();
        }
    
        public static void method() throws IOException {
            // 创建FileOutputStream对象,构造方法中绑定要输出的目的地。
            FileOutputStream fos = new FileOutputStream("/Users/liyihua/IdeaProjects/Study/src/view/study/demo33/BufferedOutputStream.txt", true);
    
            // 创建BufferedOutputStream对象,构造方法中传递FileOutputStream对象,提高FileOutputStream对象效率。
            BufferedOutputStream bos = new BufferedOutputStream(fos);
    
            // 使用BufferedOutputStream对象中的方法write,把数据写入到内部冲区中。
            byte[] bytes = "abc".getBytes();
            bos.write(bytes);
    
            // 使用BufferedOutputStream对象中的方法flush,把内部冲区中的数据,刷新到文件中。
            bos.flush();
    
            // 释放资源(会先调用flush方法刷新数据,第4步可以省略)。
            bos.close();
            fos.close();
    
        }
    }

    运行生成文件BufferedOutputStream.txt文件,文件的内容如下:

    BufferedInputStream —— 字节缓冲输入流

    举例:读取文件上例中生成的BufferedOutputStream.txt文件。

    使用步骤:

    1.创建FileInputStream对象,构造方法中绑定要读取的效据源。
    2.创建BufferedInputStream对象,构造方法中传递FileInputStream对象,提高FileInputsStream对象的读取效率
    3.使用BufferedInputStream对象中的方法read,读取文件。
    4.释放资源。
    import java.io.BufferedInputStream;
    import java.io.FileInputStream;
    import java.io.IOException;
    
    public class DemoBufferedInputStream {
        public static void main(String[] args) throws IOException {
            method();
        }
    
        private static void method() throws IOException {
            // 创建FileInputStream对象,构造方法中绑定要读取的效据源。
            FileInputStream fis = new FileInputStream(
                    "/Users/liyihua/IdeaProjects/Study/src/view/study/demo33/BufferedOutputStream.txt"
            );
    
            // 创建BufferedInputStream对象,构造方法中传递FileInputStream对象,提高FileInputsStream对象的读取效率
            BufferedInputStream bis = new BufferedInputStream(fis);
    
            // 使用BufferedInputStream对象中的方法read,读取文件。
            int len1 = bis.read();
            System.out.println(len1);
    
            int len2 = bis.read();
            System.out.println(len2);
    
            int len3 = bis.read();
            System.out.println(len3);
    
            // 第四次读取的时候,所以的字节都已经给读取过了,返回-1
            int len4 = bis.read();
            System.out.println(len4);
    
            // 释放资源
            bis.close();
            fis.close();
        }
    }

    控制台输出:

    97
    98
    99
    -1

    效率测试

    /**
     * 举例:不同方法,拷贝图片的速度,来测试效率
     * 
     * 文件复制的步骤(不使用缓冲):
     * 1.创建一个字节输入流对象,构造方法中绑定要读取的数据源。
     * 2.创建一个字节输出流对象,构造方法中绑定要写入的目的地。
     * 3.使用字节输入流对象中的方法read,读取文件。
     * 4.使用字节输出流中的方法write,把读取到的字节写入到目的地的文件中。
     * 5.释放资源。
     * 
     * 文件复制的步骤(使用缓冲):
     * 1.创建字节缓冲输入流对象,构造方法中传递字节输入流。
     * 2.创建字节缓冲输出流对象,构造方法中传递字节输岀流。
     * 3.使用字节缓冲输入流对象中的方法read,读取文件。
     * 4.使用字节缓冲输出流中的方法wite,把读取的数据写入到内部缓冲区中。
     * 5.释放资源(会先把缓冲区中的数据,刷新到文件中)。
     */

    定义三个方法:

    /**
     * 不使用缓冲字节输入输出流,
     * 一个一个字节的方式。
     */
    public static void method1() throws IOException {
        FileInputStream fis = new FileInputStream("/Users/liyihua/IdeaProjects/Study/src/view/study/demo33/test.jpg");
        FileOutputStream fos = new FileOutputStream("/Users/liyihua/IdeaProjects/Study/src/view/study/demo33/copy1.jpg");
    
        int len = 0;
        while ((len = fis.read()) != -1) {
            fos.write(len);
        }
    
        fis.close();
        fos.close();
    }
    /**
     * 不使用缓冲字节输入输出流,
     * 一次读取多个字节的方式。
     */
    public static void method2() throws IOException {
        FileInputStream fis = new FileInputStream("/Users/liyihua/IdeaProjects/Study/src/view/study/demo33/test.jpg");
        FileOutputStream fos = new FileOutputStream("/Users/liyihua/IdeaProjects/Study/src/view/study/demo33/copy2.jpg");
    
        byte[] bytes = new byte[1024];
        int len = 0;
        while ((len = fis.read(bytes)) != -1) {
            fos.write(bytes, 0, len);
        }
    
        fis.close();
        fos.close();
    }
    /**
     * 使用缓冲字节输入输出流
     */
    public static void method3() throws IOException {
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("/Users/liyihua/IdeaProjects/Study/src/view/study/demo33/test.jpg"));
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("/Users/liyihua/IdeaProjects/Study/src/view/study/demo33/copy3.jpg"));
    
        byte[] bytes = new byte[1024];
        int len = 0;
        while ((len = bis.read(bytes)) != -1) {
            bos.write(bytes, 0, len);
        }
    
        bos.close();
        bis.close();
    }

    测试这三个方法的效率:

    public class DemoEfficiency {
        public static void main(String[] args) throws IOException {
            // 方法1效率测试
            long method1StartTime = System.currentTimeMillis();
            method1();
            long method1EndTime = System.currentTimeMillis();
            System.out.println("使用方法1,文件复制耗时(毫秒):" + (method1EndTime - method1StartTime));
    
            // 方法2效率测试
            long method2StartTime = System.currentTimeMillis();
            method2();
            long method2EndTime = System.currentTimeMillis();
            System.out.println("使用方法2,文件复制耗时(毫秒):" + (method2EndTime - method2StartTime));
    
            // 方法3效率测试
            long method3StartTime = System.currentTimeMillis();
            method3();
            long method3EndTime = System.currentTimeMillis();
            System.out.println("使用方法3,文件复制耗时(毫秒):" + (method3EndTime - method3StartTime));
        }
    }

    控制台输出:

    使用方法1,文件复制耗时(毫秒):30268
    使用方法2,文件复制耗时(毫秒):53
    使用方法3,文件复制耗时(毫秒):21

    文件大小:8,392,028 字节(磁盘上的 8.4 MB)

    运行程序,生成:copy1.jpg、copy2.jpg、copy3.jpg三个文件

    可以看出,使用缓冲字节输入输出流效率极高。

    字符缓冲流

    构造方法

    BufferedReader(Reader in)
    BufferedReader(Reader in, int sz)
    // 创建一个新的缓冲字符输入流
    
    BufferedWriter(Writer out)
    BufferedWriter(Writer out, int sz)
    // 创建一个新的缓冲字符输出流
    参数:
    Writer out:字符输出流
    Reader in:字符输入流
    int sz:缓冲区大小

    BufferedWriter —— 字符缓冲输出流

    举例:把字符文件写入到文件中

    使用步骤:

    1.创建字符缓冲输岀流对象,构造方法中传递字符输岀流。
    2.调用字符缓冲输出流中的方法write,把数据写入到內存缓冲区中。
    3.调用字符缓冲输出流中的方法flush,把内存缓冲区中的数据,刷新到文件中。
    4.释放资源。
    import java.io.BufferedWriter;
    import java.io.FileWriter;
    import java.io.IOException;
    
    public class DemoBufferedWrite {
        public static void main(String[] args) throws IOException {
            method();
        }
    
        private static void method() throws IOException {
            // 创建字符缓冲输岀流对象,构造方法中传递字符输岀流。
            BufferedWriter bw = new BufferedWriter(new FileWriter("/Users/liyihua/IdeaProjects/Study/src/view/study/demo34/BufferedWriter.txt"));
            
            // 调用字符缓冲输出流中的方法write,把数据写入到內存缓冲区中。
            bw.write("你好吖!字符缓冲输出流");
            
            // 调用字符缓冲输出流中的方法flush,把内存缓冲区中的数据,刷新到文件中。
            bw.flush();
            
            // 释放资源。
            bw.close();
        }
    }

    运行结果,生成BufferedWriter.txt文件,文件内容如下:

    如果需要换行,可以使用该类里的newLine()方法。该方法如同println()方法。

    BufferedReader —— 字符缓冲输入流

    这个类有一个特有的成员方法:

    String readLine()
    // 读取一个文本行(读取一行数据)。
    返回值:
    包含该行内容的字符串,不包含任何行终止符,如果已到达流末尾,则返回null。

    行的终止符:换行(' ')、回车(' ')、回车后直接跟着换行(' ')

    举例:读取一个文件中的每行字符。

    使用步骤:

    1.创建字符缓冲输入流对象,构造方法中传递字符输入流。
    2.使用字符缓冲输入流对象中的方法read/readLine,读取文本。
    3.释放资源。
    import java.io.BufferedReader;
    import java.io.FileReader;
    import java.io.IOException;
    
    public class DemoReader {
        public static void main(String[] args) throws IOException {
            method();
        }
    
        private static void method() throws IOException {
            // 创建字符缓冲输入流对象,构造方法中传递字符输入流。
            BufferedReader br = new BufferedReader(new FileReader("/Users/liyihua/IdeaProjects/Study/src/view/study/demo34/test"));
    
            // 使用字符缓冲输入流对象中的方法read/readLine,读取文本。
            String line;
            while ((line = br.readLine()) != null) {
                // 当每行数据都读取了后,如果再读取,则会返回null
                System.out.println(line);
            }
        }
    }

    文件test.txt内容如下:

    控制台输出:

    第1行数据
    第2行数据
    第3行数据

              

  • 相关阅读:
    前言
    echarts踩坑---容器高度自适应
    vue中刷新页面时去闪烁,提升体验方法
    2018.11.7
    07-sel-express 框架快速搭建案例
    第三方包 vue-resource
    zepto.js-定制zepto步骤
    CSS-单位em 和 rem
    ES6-个人学习大纲
    响应式布局
  • 原文地址:https://www.cnblogs.com/liyihua/p/12269827.html
Copyright © 2011-2022 走看看