Java基础 第四节 第十六课

举报
我是小白呀iamarookie 发表于 2021/09/11 02:11:21 2021/09/11
【摘要】 缓冲流 概述字节缓冲流构造方法效率测试基本流缓冲流 优化 字符缓冲流构造方法特有方法readLinenewLine 练习: 文本排序分析代码展示 概述 我们已经学习...

概述

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

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

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

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

字节缓冲流

构造方法

public BufferedInputStream(InputStream in):
 创建一个 新的缓冲输入流

public BufferedOutputStream(OutputStream out):
 创建一个新的缓冲输出流

  
 
  • 1
  • 2
  • 3
  • 4
  • 5

构造举例, 代码如下:

import java.io.*;

public class Test {
    public static void main(String[] args) throws FileNotFoundException {
        // 创建字节缓冲输入流
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("a.txt"));
        
        // 创建字节缓冲输出流
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("a.txt"));
    }
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

效率测试

查询 API, 缓冲流读写方法与基本流是一致的. 我们通过赋值大文件 (几百 MB), 测试它的效率.

基本流

基本流, 代码如下:

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

public class Test75 {
    public static void main(String[] args) {
        // 记录开始时间
        long start = System.currentTimeMillis();
        // 创建流对象
        try (
                FileInputStream fis = new FileInputStream("C:/Users/Windows/Desktop/数据清洗.rar");
                FileOutputStream fos = new FileOutputStream("C:/Users/Windows/Desktop/数据清洗 (复制).rar")
        ) {
            // 读写数据
            int b;
            while ((b = fis.read()) != -1) {
                fos.write(b);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

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

输出结果:
普通流复制时间: 70379 毫秒

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

缓冲流

import java.io.*;

public class Test76 {
    public static void main(String[] args) {
        // 记录开始时间
        long start = System.currentTimeMillis();
        // 创建流对象
        try (
                BufferedInputStream bis = new BufferedInputStream(new FileInputStream("C:/Users/Windows/Desktop/数据清洗.rar"));
                BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("C:/Users/Windows/Desktop/数据清洗 (复制).rar"))

        ) {
            // 读写数据
            int b;
            while ((b = bis.read()) != -1) {
                bos.write(b);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

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

输出结果:
缓冲流复制时间573 毫秒

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

优化

如何更快呢?

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

import java.io.*;

public class Test77 {
    public static void main(String[] args) {
        // 记录开始时间
        long start = System.currentTimeMillis();
        // 创建流对象
        try (
                BufferedInputStream bis = new BufferedInputStream(new FileInputStream("C:/Users/Windows/Desktop/数据清洗.rar"));
                BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("C:/Users/Windows/Desktop/数据清洗 (复制).rar"))

        ) {
            // 读写数据
            int len;
            byte[] bytes = new byte[8*1024];
            while ((len = bis.read(bytes)) != -1) {
                bos.write(bytes, 0, len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

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

输出结果:
缓冲流复制时间54 毫秒

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

字符缓冲流

构造方法

  • public BufferedReader(Reader in): 创建一个新的缓冲输入流
  • public BufferedWriter(Writer out): 创建一个新的缓冲输出流

构造举例, 代码如下:

public static void main(String[] args) throws IOException {
        // 创建字符缓冲输入流
        BufferedReader br = new BufferedReader(new FileReader("a.txt"));
        // 创建字符缓冲输出流
        BufferedWriter bw = new BufferedWriter(new FileWriter("c.txt"));
    }

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

特有方法

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

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

readLine

readLine 方法演示, 代码如下:

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

public class Test {
    public static void main(String[] args) 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();
    }
}

输出结果:
a
------
b
------
c
------
d
------
e
------

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

newLine

newLine 方法演示, 代码如下:

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

public class Test {
    public static void main(String[] args) throws IOException {
        // 创建流对象
        BufferedWriter bw = new BufferedWriter(new FileWriter("a.txt"));
        // 写出数据
        bw.write("你好");
        // 写出换行
        bw.newLine();
        bw.write("我是");
        bw.newLine();
        bw.write("小白");

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

输出结果:
你好
我是
小白

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

练习: 文本排序

请将文本信息恢复顺序.

3.爱上层楼,
8.却道天凉好个秋。
2.爱上层楼。
1.少年不识愁滋味,
4.为赋新词强说愁。
6. 欲说还休。
7. 欲说还休,
5. 而今识尽愁滋味,

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

分析

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

代码展示

import java.io.*;
import java.util.HashMap;
import java.util.Map;

public class Test {
    public static void main(String[] args) throws IOException {
        // 创建map集合, 保存文本数据. 键为序号, 值为文字
        HashMap<String, String> lineMap = new HashMap<>();

        // 创建流对象
        BufferedReader br = new BufferedReader(new FileReader("a.txt"));
        BufferedWriter bw = new BufferedWriter(new FileWriter("c.txt"));

        // 读取数据
        String line = null;
        while ((line = br.readLine()) != null) {
            // 解析文本
            String[] split = line.split("\\.");
            // 保存到集合
            lineMap.put(split[0], split[1]);
        }
        // 释放资源
        br.close();

        // 遍历map集合
        for (Map.Entry<String, String> entry : lineMap.entrySet()) {
            // 写出map中文本
            bw.write(entry.getKey() + ". " + entry.getValue());
            // 写出换行
            bw.newLine();
        }
        // 释放资源
        bw.close();
    }
}

输出结果:
1. 少年不识愁滋味,
2. 爱上层楼。
3. 爱上层楼,
4. 为赋新词强说愁。
5.  而今识尽愁滋味,
6.  欲说还休。
7.  欲说还休,
8. 却道天凉好个秋。

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45

文章来源: iamarookie.blog.csdn.net,作者:我是小白呀,版权归原作者所有,如需转载,请联系作者。

原文链接:iamarookie.blog.csdn.net/article/details/111602968

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。