缓冲流

121 阅读3分钟

作为IO流的入门,今天我们将会见识到更强大的流。比如能够高效的读写缓冲流,能够转换编码的转换流,能够持久化存储对象的序列化流等等。这些功能更为强大的流,都在基本的流对象的基础之上创建而来的,就像穿上铠甲的武士一样,相当于是对基本流对象的一种增强。

1.1 概述

缓冲流也叫高效流,是对四个FileXxx流的增强,所以也是四个流,按照数据类型分类:

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

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

——————————————————————————————————————

1.2 字节缓冲流

构造方法

public BufferedInputStream(InputStream in):创建一个新的缓冲输入流。 public BufferedOutputStream(OutputStream out):创建一个新的缓冲输出流。

 //创建字节缓冲输入流
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("bis.txt"));
 //创建字节缓冲输出流
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("bos.txt"));
        

效率测试

查询API,缓冲流的读写方法与基本的流是一致的,我们通过复制大文件,测试它的效率。 基本流,代码如下

private static void show1() throws IOException {
        //记录开始时间
        long start = System.currentTimeMillis();
        //创建流对象
        try (
                FileInputStream fis = new FileInputStream("a.txt");
                FileOutputStream fos = new FileOutputStream("aa.txt");
        ) {
            //读写数据
            int b;
            while ((b = fis.read()) != -1) {
                fos.write(b);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        //记录结束时间
        long end = System.currentTimeMillis();
        System.out.println("普通流复制时间:" + (end - start) + "毫秒");


    }

private static void show2() {
        //记录开始时间
        long start = System.currentTimeMillis();
        //创建流对象
        try (
                BufferedInputStream bis = new BufferedInputStream(new FileInputStream("a.txt"));
                BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("aa.txt"))
        ) {
            //读写数据
            int b;
            while ((b = bis.read()) != -1) {
                bos.write(b);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        //记录结束时间
        long end = System.currentTimeMillis();
        System.out.println("缓冲流复制时间:" + (end - start) + "毫秒");
    }
private static void show3() {
        //记录开始时间
        long start = System.currentTimeMillis();
        //创建流对象
        try (
                BufferedInputStream bis = new BufferedInputStream(new FileInputStream("a.txt"));
                BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("aa.txt"));
        ) {
            //读写数据
            int len;
            byte[] bytes = new byte[8 * 1024];
            while ((len = bis.read(bytes)) != -1) {
                bos.write(bytes, 0, len);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        //记录结束时间
        long end = System.currentTimeMillis();
        System.out.println("缓冲流使用数组赋值时间" + (end - start)+"毫秒");
    }

——————————————————————————————————————

1.3字符缓冲流

构造方法

  • public BufferedReader(Reader in):创建一个新的缓冲输入流
  • public BufferedWriter(Writer out):创建一个新的缓冲输出流
//创建字符缓冲输入流
BufferedReader br=new BufferedReader(new FileReader("br.txt"));
//创建字符缓冲输出流
BufferedWriter bw=new BufferedWriter(new FileWriter("bw.txt"));

特有方法

字符缓冲流的基本方法与普通字符流的调用方式一致,不在阐述,我们来看看他们具备的特有的方法

  • BufferedReader: public String readLine():读一行文字
  • BufferedWriter: public void newLine():写一行行的分隔符,由系统属性定义分隔符

readLine方法演示,代码如下:

 private static void show4() throws IOException {
        //创建流对象
        BufferedReader br = new BufferedReader(new FileReader("a.txt"));
        //定义字符串,保存读取的一行文字
        String line = null;
        //循环读取,读取到最后,返回null
        while ((line = br.readLine()) != null) {
            System.out.println(line);
            System.out.println("-----------");
        }

        //释放资源
        br.close();
    }

newLine方法演示,代码如下:

private static void show5() throws IOException {
        //创建流对象
        BufferedWriter bw = new BufferedWriter(new FileWriter("aa.txt"));
        //写出数据
        bw.write("黑马");
        //写出换行
        bw.newLine();
        bw.write("程序员");
        bw.close();
    }

——————————————————————————————————————

1.4 练习:文本排序

请将文本信息恢复顺序:

案例分析

  1. 逐行读取文本信息
  2. 解析文本信息到集合中
  3. 遍历集合,按顺序,写出文本信息

案例实现

private static void show6() {
        //创建map集合,保存文本数据,键为序号,值为文字
        HashMap<String, String> lineMap = new HashMap<>();

        //创建流对象
        try (
                BufferedReader br = new BufferedReader(new FileReader("a.txt"));
                BufferedWriter bw = new BufferedWriter(new FileWriter("aa.txt"));
        ) {
            //读取数据
            String line = null;
            while ((line = br.readLine()) != null) {
                //解析文本
                String[] split=line.split("\\.");
                lineMap.put(split[0], split[1]);
            }


            //遍历map集合
            for (int i = 1; i <=lineMap.size(); i++) {
                String key = String.valueOf(i);
                //写出map中的文本
                String value = lineMap.get(key);
                //写出拼接文本
                bw.write(key + "." + value);
                //写出换行
                bw.newLine();
            }


        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }