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行数据

              

  • 相关阅读:
    Atitit.随时间变色特效 ---包厢管理系统的规划
    Atitit.request http乱码的设计防止 检测与解决最近实践p825 attilax总结.doc
    Atitit.request http乱码的设计防止 检测与解决最近实践p825 attilax总结.doc
    atitit.薄伽梵歌overview  attilax 读后感
    Atitit。 《吠陀》 《梨俱吠陀》overview 经读后感  是印度上古时期一些文献的总称
    Atitit。 《吠陀》 《梨俱吠陀》overview 经读后感  是印度上古时期一些文献的总称
    atitit.薄伽梵歌overview  attilax 读后感
    Atitit 《摩奴法典》overivew 读后感 不是由国王 颁布的,而是 僧侣编制
    Atitit 《摩奴法典》overivew 读后感 不是由国王 颁布的,而是 僧侣编制
    Atitit.执行cli cmd的原理与调试
  • 原文地址:https://www.cnblogs.com/liyihua/p/12269827.html
Copyright © 2011-2022 走看看