Java基础IO篇--缓冲流

简介: Java基础IO篇--缓冲流

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第4天,点击查看活动详情

前言

缓冲流的基本原理,是在创建流对象时,会创建一个内置的默认大小的缓冲区数组,通过缓冲区读写,减少系统IO次数,从而提高读写的效率。在Java中缓冲流的实现,是与基本流一一对应的,或者换句话说,缓冲流就是在四个基本流的基础上,加入了内存缓冲,大大提高了I/O的效率。按照分类可以分为:

  • 4个基本流:
  • 字节流
  • 字节输入流:FileInputStream
  • 字节输出流:FileOutputStream
  • 字符流
  • 字符输入流:FileReader
  • 字符输出流:FileWriter
  • 4个缓冲流:
  • 字节缓冲流:
  • 字节输入缓冲流:BufferedInputStream
  • 字节输出缓冲流:BufferedOutputStream
  • 字符缓冲流:
  • 字符输入缓冲流:BufferedReader
  • 字符输出缓冲流:BufferedWriter

一、字节缓冲流

字节缓冲流主要分为字节缓冲输入流和字节缓冲输入流。

  • public BufferedInputStream(InputStream in):创建一个新的缓冲输入流。【通过一个基本的字节流得到一个缓冲流】
  • public BufferedOutputStream(OutputStream out):创建一个新的缓冲输出流。功能方法与普通的字节流一致!

基本字节流和缓冲字节流对比

/*
    普通字节流复制文件!
      将D盘io目录下面的 jdk8.exe文件拷贝到day11_io/src/copy.exe 【文件大小为202MB】
   */
public class Test {
    public static void main(String[] args) {
        // 创建2个流对象
        try (
                FileInputStream fis = new FileInputStream("D:/io/jdk8.exe");
                FileOutputStream fos = new FileOutputStream("day11_io/src/copy.exe");
        ) {
            long start = System.currentTimeMillis();
            // 创建字节数组
            byte[] bt = new byte[1024];
            int len;
            while ((len = fis.read(bt)) != -1) {
                // 写出去
                fos.write(bt, 0, len);
            }
            long end = System.currentTimeMillis();
            System.out.println("复制完毕,消耗时间为:" + (end - start) + "毫秒!");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

// 测试结果:1723毫秒!

/*
 高效字节流复制文件!
   将D盘io目录下面的 jdk8.exe文件拷贝到day11_io/src/copy.exe 【文件大小为202MB】
*/
public class Test {
    public static void main(String[] args) {
        // 创建2个流对象
        try (
                BufferedInputStream bis = new BufferedInputStream(new FileInputStream("D:/io/jdk8.exe"));
                BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("day11_io/src/copy.exe"));
        ) {
            long start = System.currentTimeMillis();
            // 创建字节数组
            byte[] bt = new byte[1024];
            int len;
            while ((len = bis.read(bt)) != -1) {
                // 写出去
                bos.write(bt, 0, len);
            }
            long end = System.currentTimeMillis();
            System.out.println("复制完毕,消耗时间为:" + (end - start) + "毫秒!");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

// 测试结果:413毫秒!

总结:上面对比可以看出字节流和字节缓冲流的用法相同,或者说字节缓冲流需要一个字节流才能创建字节缓冲流,但是在执行效率上字节缓冲流远远优于字节流

二、字符缓冲流

字符缓冲流主要分为字符缓冲输入流和字符缓冲输出流。

  • public BufferedReader(Reader in): 创建一个 新的缓冲输入流。
  • public BufferedWriter(Writer out): 创建一个新的缓冲输出流。
  • BufferedReader:public String readLine(): 读一行文字。
  • BufferedWriter:public void newLine(): 写一行行分隔符,由系统属性定义符号。
public class Test {
    public static void main(String[] args) {
        // 创建2个流对象
        try (
                BufferedReader br = new BufferedReader(new FileReader("day11_io/src/br.txt"));
                BufferedWriter bw = new BufferedWriter(new FileWriter("day11_io/src/bw.txt"));
        ) {
            // 读到的具体某行数据!
            String line;
            while ((line = br.readLine()) != null) {
                //System.out.println(line);
                // 将读到的一行数据写到bw.txt文件中
                bw.write(line);
                // 写一行就换行!
                bw.newLine(); // 等价于:bw.write("rn");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

三、缓冲流练习(文本排序)

需求:将下列文件数据恢复顺序

3.侍中、侍郎郭攸之、费祎、董允等,此皆良实,志虑忠纯,是以先帝简拔以遗陛下。愚以为宫中之事,事无大小,悉以咨之,然后施行,必得裨补阙漏,有所广益。

8.愿陛下托臣以讨贼兴复之效,不效,则治臣之罪,以告先帝之灵。若无兴德之言,则责攸之、祎、允等之慢,以彰其咎;陛下亦宜自谋,以咨诹善道,察纳雅言,深追先帝遗诏,臣不胜受恩感激。

4.将军向宠,性行淑均,晓畅军事,试用之于昔日,先帝称之曰能,是以众议举宠为督。愚以为营中之事,悉以咨之,必能使行阵和睦,优劣得所。

2.宫中府中,俱为一体,陟罚臧否,不宜异同。若有作奸犯科及为忠善者,宜付有司论其刑赏,以昭陛下平明之理,不宜偏私,使内外异法也。

1.先帝创业未半而中道崩殂,今天下三分,益州疲弊,此诚危急存亡之秋也。然侍卫之臣不懈于内,忠志之士忘身于外者,盖追先帝之殊遇,欲报之于陛下也。诚宜开张圣听,以光先帝遗德,恢弘志士之气,不宜妄自菲薄,引喻失义,以塞忠谏之路也。

9.今当远离,临表涕零,不知所言。

6.臣本布衣,躬耕于南阳,苟全性命于乱世,不求闻达于诸侯。先帝不以臣卑鄙,猥自枉屈,三顾臣于草庐之中,咨臣以当世之事,由是感激,遂许先帝以驱驰。后值倾覆,受任于败军之际,奉命于危难之间,尔来二十有一年矣。

7.先帝知臣谨慎,故临崩寄臣以大事也。受命以来,夙夜忧叹,恐付托不效,以伤先帝之明,故五月渡泸,深入不毛。今南方已定,兵甲已足,当奖率三军,北定中原,庶竭驽钝,攘除奸凶,兴复汉室,还于旧都。此臣所以报先帝而忠陛下之职分也。至于斟酌损益,进尽忠言,则攸之、祎、允之任也。

5.亲贤臣,远小人,此先汉所以兴隆也;亲小人,远贤臣,此后汉所以倾颓也。先帝在时,每与臣论此事,未尝不叹息痛恨于桓、灵也。侍中、尚书、长史、参军,此悉贞良死节之臣,愿陛下亲之信之,则汉室之隆,可计日而待也。

  • 分析:
    ① 创建文本数据对应的字符缓冲流对象
    ② 循环读取每一行(readLine),得到的是字符串数据!
    ③ 使用字符串的split方法以 . 进行切割!得到字符串数组(0索引是字符串序号,1索引是字符串文字)
    ④ 在循环外部创建Map(TreeMap),在遍历里面将字符串序号作为key,字符串文字作为value,添加到map集合
    ⑤ 遍历Map,将key和value拼接为一个新的字符串  \
  • 作业:
    将map里面的数据写出到一个文件中!
public class Test {
    public static void main(String[] args) {
        // 1. 创建1个字符高效流对象
        try (
                BufferedReader br = new BufferedReader(new FileReader("day11_io/src/br.txt"));
        ) {
            // 4. 定义一个Map集合
            TreeMap<String, String> map = new TreeMap<>();
            // 2.循环读到的具体某行数据!
            String line;
            while ((line = br.readLine()) != null) {
                // 3. 切割字符串的数据
                String[] split = line.split(".");
                // 5. 将字符串序号作为key,字符串文字作为value,添加到map集合
                map.put(split[0], split[1]);
            }
            // 6. 遍历map
            for (String key : map.keySet()) {
                System.out.println(key + "." + map.get(key));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

后记

在日常开发过程中我们使用缓冲流进行操作文件还是比较常见的,应该牢牢掌握。

喜欢我的文章的朋友点点喜欢、收藏,也欢迎朋友们评论区留下你的意见和建议,恕毅在此拜谢!


相关文章
|
1月前
|
Java 大数据
解析Java中的NIO与传统IO的区别与应用
解析Java中的NIO与传统IO的区别与应用
|
6天前
|
Java Android开发
解决Android编译报错:Unable to make field private final java.lang.String java.io.File.path accessible
解决Android编译报错:Unable to make field private final java.lang.String java.io.File.path accessible
22 1
|
10天前
|
存储 缓存 Java
15 Java IO流(File类+IO流+字节流+字符流+字节编码)
15 Java IO流(File类+IO流+字节流+字符流+字节编码)
33 3
|
19天前
|
安全 Java Linux
(七)Java网络编程-IO模型篇之从BIO、NIO、AIO到内核select、epoll剖析!
IO(Input/Output)方面的基本知识,相信大家都不陌生,毕竟这也是在学习编程基础时就已经接触过的内容,但最初的IO教学大多数是停留在最基本的BIO,而并未对于NIO、AIO、多路复用等的高级内容进行详细讲述,但这些却是大部分高性能技术的底层核心,因此本文则准备围绕着IO知识进行展开。
|
19天前
|
存储 Java Unix
(八)Java网络编程之IO模型篇-内核Select、Poll、Epoll多路复用函数源码深度历险!
select/poll、epoll这些词汇相信诸位都不陌生,因为在Redis/Nginx/Netty等一些高性能技术栈的底层原理中,大家应该都见过它们的身影,接下来重点讲解这块内容。
|
1月前
|
存储 安全 Java
【Java】已解决java.io.ObjectStreamException异常
【Java】已解决java.io.ObjectStreamException异常
19 1
|
1月前
|
Java 程序员
【Java】已解决java.io.UnsupportedEncodingException异常
【Java】已解决java.io.UnsupportedEncodingException异常
33 0
|
1月前
|
安全 Java
【Java】已解决java.io.InterruptedIOException异常
【Java】已解决java.io.InterruptedIOException异常
32 0
|
1月前
|
Java 大数据
解析Java中的NIO与传统IO的区别与应用
解析Java中的NIO与传统IO的区别与应用
|
3月前
|
存储 Java 数据安全/隐私保护
从零开始学习 Java:简单易懂的入门指南之IO字符流(三十一)
从零开始学习 Java:简单易懂的入门指南之IO字符流(三十一)