Java基础:缓冲流

了解了IO流,再说一说一些更强大的流。比如能够高效读写的缓冲流,能够转换编码的转换流,能够持久化存储对象的序列化流等等。这些功能更为强大的流,都是在基本的流对象基础之上创建而来的,就像穿上铠甲的武士一样,相当于是对基本流对象的一种增强。咱们先说说缓冲流。

1.1 概述

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

  • 字节缓冲流BufferedInputStreamBufferedOutputStream

  • 字符缓冲流BufferedReaderBufferedWriter

缓冲流的基本原理,是在创建流对象时,会创建一个内置的默认大小的缓冲区数组,通过缓冲区读写,减少系统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,缓冲流读写方法与基本的流是一致的,我们通过复制大文件(5.21MB),测试它的效率。

  • 基本流,代码如下:
package com.dcxuexi.java24;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

/***
 * @Title BufferedDemo
 * @Description TOTD
 * @Auter DongChuang
 * @Date 2022/12/13 22:15
 * @Version 1.0.0
 */
public class BufferedDemo {
    public static void main(String[] args) throws IOException {
        // 记录开始时间
        long start = System.currentTimeMillis();
        // 创建流对象
        FileInputStream fis = fis = new FileInputStream("D:\\java\\javaCode\\dingtalk_downloader.exe");
        FileOutputStream fos = fos = new FileOutputStream("D:\\java\\javaCode\\File\\dingtalk_downloader.exe");
        // 读写数据
        int b;
        while ((b = fis.read()) != -1) {
            fos.write(b);
        }
        fos.close();
        fis.close();

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

在这里插入图片描述

  • 缓冲流,代码如下:
package com.dcxuexi.java24;

import java.io.*;

/***
 * @Title BufferedDemo02
 * @Description TOTD
 * @Auter DongChuang
 * @Date 2022/12/13 22:35
 * @Version 1.0.0
 */
public class BufferedDemo02 {
    public static void main(String[] args) throws IOException {
        // 记录开始时间
        long start = System.currentTimeMillis();
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("D:\\java\\javaCode\\dingtalk_downloader.exe"));
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("D:\\java\\javaCode\\File\\dingtalk_downloader02.exe"));
        // 读写数据
        int b;
        while ((b = bis.read()) != -1) {
            bos.write(b);
        }
        // 释放资源
        bos.close();
        bis.close();

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

在这里插入图片描述

如何更快呢?

使用数组的方式,代码如下:

public class BufferedDemo02 {
    public static void main(String[] args) throws IOException {
        // 记录开始时间
        long start = System.currentTimeMillis();
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("D:\\java\\javaCode\\dingtalk_downloader.exe"));
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("D:\\java\\javaCode\\File\\dingtalk_downloader03.exe"));
        // 读写数据
        int len;
        byte[] bytes = new byte[8*1024];
        while ((len = bis.read(bytes)) != -1) {
            bos.write(bytes,0,len);
        }
        // 释放资源
        bos.close();
        bis.close();

        // 记录结束时间
        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"));

特有方法

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

  • BufferedReaderpublic String readLine(): 读一行文字。

  • BufferedWriterpublic void newLine(): 写一行行分隔符,由系统属性定义符号。

readLine方法演示,代码如下:

package com.dcxuexi.java24;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

/***
 * @Title BufferedReaderDemo
 * @Description TOTD
 * @Auter DongChuang
 * @Date 2022/12/14 20:19
 * @Version 1.0.0
 */
public class BufferedReaderDemo {
    public static void main(String[] args) throws IOException {
        // 创建流对象
        BufferedReader bufferedReader = new BufferedReader(new FileReader("D:\\java\\javaCode\\bufferedReader\\bufferedReader.txt"));
        // 定义字符串,保存读取的一行文字
        String line = null;
        int i = 1;
        // 循环读取,读取到最后返回null
        while ((line = bufferedReader.readLine())!=null){
            System.out.println("第"+ i +"行-->"+line);
            i++;
        }
        // 释放资源
        bufferedReader.close();
    }
}

在这里插入图片描述

newLine方法演示,代码如下:

package com.dcxuexi.java24;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;

/***
 * @Title BufferedWriterDemo
 * @Description TOTD
 * @Auter DongChuang
 * @Date 2022/12/14 20:29
 * @Version 1.0.0
 */
public class BufferedWriterDemo {
    public static void main(String[] args) throws IOException {
        // 创建流对象
        BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter("D:\\java\\javaCode\\bufferedReader\\bufferedWriter.txt"));

        bufferedWriter.write("石家庄赵子龙"); // 写出数据
        bufferedWriter.newLine();// 写出换行
        bufferedWriter.write("包头吕布"); // 写出数据
        bufferedWriter.newLine();// 写出换行
        bufferedWriter.write("合肥包拯"); // 写出数据

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

在这里插入图片描述

1.4 练习:文本排序(春江花月夜)

请将文本信息恢复顺序。

18.江畔何人初见月?江月何年初照人?
25.此时相望不相闻,愿逐月华流照君。
17.江天一色无纤尘,皎皎空中孤月轮。
19.人生代代无穷已,江月年年望相似。
12.【作者】张若虚 【朝代】唐
21.白云一片去悠悠,青枫浦上不胜愁。
28.江水流春去欲尽,江潭落月复西斜。
29.斜月沉沉藏海雾,碣石潇湘无限路。
26.鸿雁长飞光不度,鱼龙潜跃水成文。
14.滟滟随波千万里,何处春江无月明!
20.不知江月待何人,但见长江送流水。
11.春江花月夜
22.谁家今夜扁舟子?何处相思明月楼?
13.春江潮水连海平,海上明月共潮生。
30.不知乘月几人归,落月摇情满江树。
23.可怜楼上月裴回,应照离人妆镜台。
24.玉户帘中卷不去,捣衣砧上拂还来。
15.江流宛转绕芳甸,月照花林皆似霰;
27.昨夜闲潭梦落花,可怜春半不还家。
16.空里流霜不觉飞,汀上白沙看不见。

案例分析

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

案例实现

package com.dcxuexi.java24;

import java.io.*;
import java.util.HashMap;
import java.util.Set;
import java.util.TreeSet;

/***
 * @Title BufferedTest
 * @Description TOTD
 * @Auter DongChuang
 * @Date 2022/12/14 20:43
 * @Version 1.0.0
 */
public class BufferedTest {
    public static void main(String[] args) throws IOException {
        // 创建map集合,保存文本数据,键为序号,值为文字
        HashMap<String, String> lineMap = new HashMap<>();
        // 创建流对象
        BufferedReader br = new BufferedReader(new FileReader("D:\\java\\javaCode\\bufferedReader\\gushi.txt"));
        BufferedWriter bw = new BufferedWriter(new FileWriter("D:\\java\\javaCode\\bufferedReader\\tangshi.txt"));
        // 读取数据
        String line = null;
        while ((line = br.readLine())!=null){
            // 解析文本
            String[] split = line.split("\\.");
            // 保存到集合
            lineMap.put(split[0],split[1]);
        }
        // 释放资源
        br.close();
        Set<String> key = lineMap.keySet();
        //创建TreeSet排序的lambda表达式; 相比于传统方式,代码量上有了很大的减少;
        Set<String> treeSet = new TreeSet<String>(String::compareTo);
        treeSet.addAll(key);
        // 遍历map集合
        for (String keyStr : treeSet) {
            // 写出拼接文本
            bw.write(lineMap.get(keyStr));
            // 写出换行
            bw.newLine();
        }
        // 释放资源
        bw.close();
    }
}

在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mr.D.Chuang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值