• 第八章、缓冲流

  • 缓冲流概述

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

  输入缓冲流 输出缓冲流
字节缓冲流 BufferedInputStream BufferedOutputStream
字符缓冲流 BufferedReader BufferedWriter

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

  • 字节缓冲输出流 BufferedOutputStream

    • java.io.BufferedOutputStream extends OutputStream

    • 继承自父类的方法

      • void close()

      • void flush()

      • void write(byte[] b)

      • void write(byte[] b,int off,int len)

      • abstract void write(int b)

    • 构造方法

      • BufferedOutputStream(OutputStream out):创建一个新的缓冲流,以将数据写入指定的底层输出流。

      • BufferedOutputStream(OutputStream out,int size):创建一个新的缓冲输出流,以将具有指定缓冲区大小的数据写入指定的底层输出流。

    • 构造方法的参数::

      • OutputStream out :字节输出流

        • 我们可以传递FileOutputStream,缓冲流会给FileOutputStream增加一个缓冲区,提高FileOutputStream的效率。

      • int size:指定缓冲流内部缓冲区的大小,不指定则默认大小。

    • 字段摘要:

      • protected byte[] buf 存储数据的内部缓冲区

      • protected int count 缓冲区的有效字节数

    • 使用步骤

      1. 创建FileOutputStream 对象,构造方法中绑定要输出的目的地;

      2. 创建BufferedOutputStream 对象,构造方法中传递 FileOutputStream 对象,提高FileOutputStream对象的效率;

      3. 使用BufferedOutputStream 对象中的方法write,把数据写入到内部缓冲区中;

      4. 使用BufferedOutStream 对象中的方法flush,把内部缓冲区的数据,刷新到文件中;

      5. 释放资源(会先调用flush方法刷新数据,第4步可以省略)。

    • 代码片段

    • 1 FileOutputStream fos = new FileOutputStream("10_IO\\a.txt");
      2 BufferedOutputStream bos = new BufferedOutputStream(fos);
      3 bos.write("我把数据写入到内部缓冲区中".getBytes());
      4 bos.flush();
      5 bos.close();
      6 fos.close();
  • 字节缓冲输入流 BufferedInputStream

    • java.io.BufferedInputStream extends InputStream

    • 构造方法:

      • BufferedInputStream(IntputStream in)

      • BufferedInputStream(InputStream in ,int size)

      • 构造方法的参数:

        • InputStream in:字节输入流,缓冲流会给FileInputStream增加一个缓冲区,提高FileInputStream的读取效率

        • int size :指定缓冲流内部缓冲区的大小,不指定则是默认大小。

    • 继承自父类的成员方法:

      • int read()

      • int read(byte[] b)

      • void close()

    • 使用步骤

      1. 创建FileInputStream 对象,构造方法中绑定要读取的目的地;

      2. 创建BufferedInputStream 对象,构造方法中传递FileInputStream对象;

      3. 使用BufferedInputStream对象中的方法read,读取文件;

      4. 释放资源。

    • 代码片段【下面两个代码片段是一样的,只是write的重载。】

1 FileInputStream fis = new FileInputStream("10_IO\\a.txt");
2 BufferedInputStream bis = new BufferedInputStream(fis);
3 int len = 0;//记录每次读取到的字节
4 while((len = bis.read())!=-1){
5 System.out.println(len);
6 }
7 bis.close();
8 fis.close();
1 FileInputStream fis = new FileInputStream("10_IO\\a.txt");
2 BufferedInputStream bis = new BufferedInputStream(fis);
3 byte[] bytes =new byte[1024];//存储每次读取的数据
4 int len = 0; //记录每次读取的有效字节个数
5 while((len = bis.read(bytes))!=-1){
6 System.out.println(new String(bytes,0,len));
7 }
8 bis.close();
9 fis.close();
  • 缓冲流效率测试——复制文件

    • 没有使用缓冲流的复制文件

 1 /*
2 文件复制练习:一读一写
3
4 明确:
5 数据源: c:\\1.jpg
6 数据的目的地: d:\\1.jpg
7
8 文件复制的步骤:
9 1.创建一个字节输入流对象,构造方法中绑定要读取的数据源
10 2.创建一个字节输出流对象,构造方法中绑定要写入的目的地
11 3.使用字节输入流对象中的方法read读取文件
12 4.使用字节输出流中的方法write,把读取到的字节写入到目的地的文件中
13 5.释放资源
14 文件的大小:780,831 字节
15 一次读写一个字节:6043毫秒
16 使用数组缓冲读取多个字节,写入多个字节:10毫秒
17 */
18 public class Demo01CopyFile {
19 public static void main(String[] args) throws IOException {
20 long s = System.currentTimeMillis();
21 //1.创建一个字节输入流对象,构造方法中绑定要读取的数据源
22 FileInputStream fis = new FileInputStream("c:\\1.jpg");
23 //2.创建一个字节输出流对象,构造方法中绑定要写入的目的地
24 FileOutputStream fos = new FileOutputStream("d:\\1.jpg");
25 //一次读取一个字节写入一个字节的方式
26 //3.使用字节输入流对象中的方法read读取文件
27 /*int len = 0;
28 while((len = fis.read())!=-1){
29 //4.使用字节输出流中的方法write,把读取到的字节写入到目的地的文件中
30 fos.write(len);
31 }*/
32
33 //使用数组缓冲读取多个字节,写入多个字节
34 byte[] bytes = new byte[1024];
35 //3.使用字节输入流对象中的方法read读取文件
36 int len = 0;//每次读取的有效字节个数
37 while((len = fis.read(bytes))!=-1){
38 //4.使用字节输出流中的方法write,把读取到的字节写入到目的地的文件中
39 fos.write(bytes,0,len);
40 }
41
42 //5.释放资源(先关写的,后关闭读的;如果写完了,肯定读取完毕了)
43 fos.close();
44 fis.close();
45 long e = System.currentTimeMillis();
46 System.out.println("复制文件共耗时:"+(e-s)+"毫秒");
47 }
48
49 }
 
    • 使用了缓冲流的复制文件

 1 /*
2 文件复制练习:一读一写
3
4 明确:
5 数据源: c:\\1.jpg
6 数据的目的地: d:\\1.jpg
7 文件复制的步骤:
8 1.创建字节缓冲输入流对象,构造方法中传递字节输入流
9 2.创建字节缓冲输出流对象,构造方法中传递字节输出流
10 3.使用字节缓冲输入流对象中的方法read,读取文件
11 4.使用字节缓冲输出流中的方法write,把读取的数据写入到内部缓冲区中
12 5.释放资源(会先把缓冲区中的数据,刷新到文件中)
13
14 文件的大小:780,831 字节
15 一次读写一个字节:32毫秒
16 使用数组缓冲读取多个字节,写入多个字节:5毫秒
17 */
18 public class Demo02CopyFile {
19 public static void main(String[] args) throws IOException {
20 long s = System.currentTimeMillis();
21 //1.创建字节缓冲输入流对象,构造方法中传递字节输入流
22 BufferedInputStream bis = new BufferedInputStream(new FileInputStream("c:\\1.jpg"));
23 //2.创建字节缓冲输出流对象,构造方法中传递字节输出流
24 BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("d:\\1.jpg"));
25 //3.使用字节缓冲输入流对象中的方法read,读取文件
26 //一次读取一个字节写入一个字节的方式
27 /*int len = 0;
28 while((len = bis.read())!=-1){
29 bos.write(len);
30 }*/
31
32 //使用数组缓冲读取多个字节,写入多个字节
33 byte[] bytes = new byte[1024];
34 int len = 0;
35 while((len = bis.read(bytes))!=-1){
36 bos.write(bytes,0,len);
37 }
38
39 bos.close();
40 bis.close();
41
42 long e = System.currentTimeMillis();
43 System.out.println("复制文件共耗时:"+(e-s)+"毫秒");
44 }
45 }
 
    • 当文件很大时,使用缓冲流的效率体现的会更明显。

  • 字符缓冲输出流 BufferedWriter 

    • java.io.BufferedWriter extends Writer

    • 构造方法:

      • BufferedWrite(Write out):创建一个使用默认大小输出缓冲区的缓冲字符输出流。

      • BufferedWrite(Write out ,int size):创建一个使用指定大小输出缓冲区的缓冲字符输出流。

      • 构造方法的参数:

        • Write out :字符输出流

        • int size:指定缓冲区的大小,不指定则默认大小。

    • 继承自父类的成员方法:

      • void write(int c)

      • void write(char[] cbuf)

      • abstract void write(char[] cbuf,int off,int len)

      • void write(String str)

      • void write(String str,int off,int len)

      • void flush()

      • void close()

    • 特有的成员方法:

      • void newLine()写入一个行分隔符。会根据不同的操作系统,获取不同表现形式的行分隔符。

        • 换行的符号在不同的操作系统的上的不同表示形式:

        • Windows \r\n
          Linux /n
          max /r
    • 使用步骤

      1. 创建字符缓冲输出流对象,构造方法中传递字符输出流;

      2. 调用字符输出流中的方法write,把数据写入到内存缓冲区中;

      3. 调用字符缓冲输出流中的方法flush,把内存缓冲区中的数据,刷新到文件中;

      4. 释放资源

    • 代码片段:

 1 //System.out.println();//里面传递的就是 newLine();
2 //1.创建字符缓冲输出流对象,构造方法中传递字符输出流
3 BufferedWriter bw = new BufferedWriter(new FileWriter("10_IO\\c.txt"));
4 //2.调用字符缓冲输出流中的方法write,把数据写入到内存缓冲区中
5 for (int i = 0; i <10 ; i++) {
6 bw.write("黄蓉小龙女");
7 //bw.write("\r\n");
8 bw.newLine();
9 }
10 //3.调用字符缓冲输出流中的方法flush,把内存缓冲区中的数据,刷新到文件中
11 bw.flush();
12 //4.释放资源
13 bw.close();
System.out.println()中传递的就是newLine():

  • 字符缓冲输入流 BufferedReader

    • java.io.BufferedReader extends Reader

    • 构造方法:

      • BufferedReader(Reader in)

      • BufferedReader(Reader in,int size)

      • 构造方法的参数:

        • Reader in :字符输入流。缓冲流会给字符输入流增加一个缓冲区,提高字符输入流的效率。

        • int size :指定缓冲区的大小,不指定则默认大小。

    • 继承自父类的成员方法:

      • int read()

      • int read(char[] cbuf)

      • void close()

    • 特有的成员方法:

      • String readLine():读取一个文本行——读取一行数据。

        • 行的终止符:通过下列字符之一即可认为某行已终止:换行('\n')、回车('\r')或则回车后直接跟着换行(\r\n)。

        • 返回值:包含该行内容的字符串,不包含任何行终止符,如果已达到流末尾,则返回null。

    • 使用步骤:

      1. 创建字符缓冲输入流对象,构造方法中传递字符输入流;

      2. 使用字符缓冲输入流对象中的方法read/readLine读取文本;

      3. 释放资源。

    • 代码片段

    • 1 //1.创建字符缓冲输入流对象,构造方法中传递字符输入流
      2 BufferedReader br = new BufferedReader(new FileReader("10_IO\\c.txt"));
      3 //2.使用字符缓冲输入流对象中的方法read/readLine读取文本
      4 String line;
      5 while((line = br.readLine())!=null){
      6 System.out.println(line);
      7 }
      8 //3.释放资源
      9 br.close();
  • 对文本的内容进行排序

    • 题目要求:

      • 对文本的内容进行排序

      • 按照(1,2,3....)顺序排序

    • 原文片段:

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

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

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

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

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

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

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

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

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

    • 分析

      • 1.创建一个HashMap集合对象,可以:存储每行文本的序号(1,2,3,..);value:存储每行的文本

      • 2.创建字符缓冲输入流对象,构造方法中绑定字符输入流

      • 3.创建字符缓冲输出流对象,构造方法中绑定字符输出流

      • 4.使用字符缓冲输入流中的方法readline,逐行读取文本

      • 5.对读取到的文本进行切割,获取行中的序号和文本内容

      • 6.把切割好的序号和文本的内容存储到HashMap集合中(key序号是有序的,会自动排序1,2,3,4..)

      • 7.遍历HashMap集合,获取每一个键值对

      • 8.把每一个键值对,拼接为一个文本行

      • 9.把拼接好的文本,使用字符缓冲输出流中的方法write,写入到文件中

      • 10.释放资源

    • 代码实现

 1 //1.创建一个HashMap集合对象,可以:存储每行文本的序号(1,2,3,..);value:存储每行的文本
2 HashMap<String,String> map = new HashMap<>();
3 //2.创建字符缓冲输入流对象,构造方法中绑定字符输入流
4 BufferedReader br = new BufferedReader(new FileReader("10_IO\\in.txt"));
5 //3.创建字符缓冲输出流对象,构造方法中绑定字符输出流
6 BufferedWriter bw = new BufferedWriter(new FileWriter("10_IO\\out.txt"));
7 //4.使用字符缓冲输入流中的方法readline,逐行读取文本
8 String line;
9 while((line = br.readLine())!=null){
10 //5.对读取到的文本进行切割,获取行中的序号和文本内容
11 String[] arr = line.split("\\.");
12 //6.把切割好的序号和文本的内容存储到HashMap集合中(key序号是有序的,会自动排序1,2,3,4..)
13 map.put(arr[0],arr[1]);
14 }
15
16 //7.遍历HashMap集合,获取每一个键值对
17 for(String key : map.keySet()){
18 String value = map.get(key);
19 //8.把每一个键值对,拼接为一个文本行
20 line = key + "." + value;
21 //9.把拼接好的文本,使用字符缓冲输出流中的方法write,写入到文件中
22 bw.write(line);
23 bw.newLine();//写换行
24 }
25 //10.释放资源
26 bw.close();
27 br.close();
    • 排序后的文章片段

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

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

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

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

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

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

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

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

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

File类与常用IO流第八章——缓冲流的更多相关文章

  1. File类与常用IO流第四章——IO字节流

    一切文件在存储时,都是以二进制数字的形式保存的,都是一个一个字节.无论使用什么样的流对象,底层传输的始终是二进制数据. 字节输出流 OutputStream java.io.OutputStream ...

  2. File类与常用IO流第一章File类

    第一章:File类 一.1个重点单词: file:文件:directory:文件夹/目录:path:路径(绝对路径:absolutePath) 二.4个静态成员变量: 1.static String ...

  3. File类与常用IO流第七章——Properties集合

    Properties概述 java.util.Properties extends Hashtable<k,v> implements Map<k,v> Properties类 ...

  4. File类与常用IO流第二章过滤器

    在第一章中,有一个练习使用递归搜索文件 1 public static void main(String[] args) { 2 File f=new File("E:\\aaa" ...

  5. File类与常用IO流第九章——转换流

    第九章.转换流 字节编码和字符集 编码:按照某种规则将字符以二进制存储到计算机中. 解码:将存储在计算机中的二进制数按照某种规则解析显示出来. 字符编码:Character Encoding ,就是一 ...

  6. File类与常用IO流第十一章——打印流

    第十一章.打印流 概述:java.io.PrintStream extends OutputStream,为其他输出流添加了功能,使题目能够方便的打印各种数据值表示形式. 特点: 只负责数据的输出,不 ...

  7. File类与常用IO流第十章——序列化流

    第十章.序列化流 序列化流和反序列化流概述 序列化:用一个字节序列表示一个对象,该字节序列包含该对象的数据.对象的类型和对象中存储的属性等等信息.字节序列写出到文件后,相当于文件中持久保存了一个对象的 ...

  8. File类与常用IO流第五章——IO字符流

    字符流,只能操作文本文件,不能操作图片.视频等非文本文件 字符输入流 java.io.Reader 字符输入流中一些共性的成员方法 int read():读取单个字符并返回. int read(cha ...

  9. File类与常用IO流第六章——使用try...catch...finally处理流中的异常

    在JDK1.7之前: 1 package com.itheima.demo06.trycatch; 2 3 import java.io.FileWriter; 4 import java.io.IO ...

随机推荐

  1. Torchvision模型微调

    Torchvision模型微调 本文将深入探讨如何对 torchvision 模型进行微调和特征提取,所有这些模型都已经预先在1000类的magenet数据集上训练完成.将深入介绍如何使用几个现代的C ...

  2. 在NVIDIA(CUDA,CUBLAS)和Intel MKL上快速实现BERT推理

    在NVIDIA(CUDA,CUBLAS)和Intel MKL上快速实现BERT推理 直接在NVIDIA(CUDA,CUBLAS)或Intel MKL上进行高度定制和优化的BERT推理,而无需tenso ...

  3. RTOS诊断和错误检查

    RTOS诊断和错误检查 RTOS diagnostics and error checking 查看RTOS显示系列 错误处理不太可能是任何用于嵌入式系统应用程序的操作系统的主要功能.这是资源限制的必 ...

  4. TcaplusDB祝大家端午安康!

    "五月五,端午到,赛龙舟,真热闹.吃粽子,带香包,蚊虫不来身边闹."这首脍炙人口.描绘着端午节风俗的儿歌,想必大家都听过. 每年的农历五月初五,是我国四大传统节日(春节.清明节.端 ...

  5. Qt自定义信号槽的使用浅析+实例

    1. Qt中自定义信号槽的使用 Qt框架提供的信号槽在某些特定场景下是无法满足我们的项目需求的,因此我们还设计自己需要的的信号和槽,使用connect()对自定义的信号槽进行连接. 如果想要使用自定义 ...

  6. cmd快捷键设置

    操作系统:windows7 x64 目的:像在任意空白处右键都有新建文档的功能一样,将cmd添加到右键里. 操作:百度经验 http://jingyan.baidu.com/article/948f5 ...

  7. 6.10考试总结(NOIP模拟6)

    前言 就这题考的不咋样果然还挺难改的.. T1 辣鸡 前言 我做梦都没想到这题正解是模拟,打模拟赛的时候看错题面以为是\(n\times n\)的矩阵,喜提0pts. 解题思路 氢键的数量计算起来无非 ...

  8. 【题解】Luogu P3110 [USACO14DEC]驮运Piggy Back

    [题解]Luogu P3110 [USACO14DEC]驮运Piggy Back 题目描述 Bessie and her sister Elsie graze in different fields ...

  9. base64的实现原理

    base64是处理二进制数据的一种编码方式,可用于把二进制数据编码成64个可打印的字符. 学习base64之前,先了解一下什么是字节与编码 什么是字节 互联网中的数据都是用字节来表示的,一个字节有8位 ...

  10. Windows10 上Docker 安装运行Gitlab

    准备条件 安装好Docker For Windows客户端. 配置好Docker 阿里云加速镜像地址. 检查Docker版本,大于等于v19. 拉取Gitlab镜像 docker pull gitla ...