• 第八章、缓冲流

  • 缓冲流概述

缓冲流,也叫高效流,是对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. CVPR2020论文解读:3D Object Detection三维目标检测

    CVPR2020论文解读:3D Object Detection三维目标检测 PV-RCNN:Point-Voxel Feature Se tAbstraction for 3D Object Det ...

  2. Kubeedge Edged概述

    Kubeedge Edged概述 Overview EdgeD是管理节点生命周期的边缘节点模块.它可以帮助用户在边缘节点上部署容器化的工作负载或应用程序.这些工作负载可以执行任何操作,从简单的远程遥测 ...

  3. 使用Nucleus SE实时操作系统

    使用Nucleus SE实时操作系统 Using the Nucleus SE real-time operating system 到目前为止,在本系列文章中,我们详细介绍了Nucleus SE提供 ...

  4. Git_远程仓库fork操作

    fork操作:当选择 fork,相当于自己有了一份原项目的拷贝,当然这个拷贝只是针对当时的项目文件,如果后续原项目文件发生改变,你必须通过其他的方式去同步. 使用场景:一般来说,不需要使用 fork ...

  5. 2、java数据结构和算法:单链表: 反转,逆序打印, 合并二个有序链表,获取倒数第n个节点, 链表的有序插入

    什么也不说, 直接上代码: 功能点有: 1, 获取尾结点 2, 添加(添加节点到链表的最后面) 3, 添加(根据节点的no(排名)的大小, 有序添加) 4, 单向链表的 遍历 5, 链表的长度 6, ...

  6. 牛客网论坛最具争议的Java面试成神笔记,牛客网下载量已突破十万

    程序员内部一直流传这一句话: 面试看牛客 刷题看力扣 牛客网作为国内最牛的程序员面试网站,一直在程序员内部颇负盛名,其中用户更是卧虎藏龙! 有国内一线大厂的企业招聘 还有一些低调的互联网大牛实力就和天 ...

  7. 日常Bug排查-Nginx重复请求?

    日常Bug排查-Nginx重复请求? 前言 日常Bug排查系列都是一些简单Bug排查,笔者将在这里介绍一些排查Bug的简单技巧,其中不乏一些看起来很低级但很容易犯的问题. 问题现场 有一天运维突然找到 ...

  8. 七、SSL加密网站(待解决)

    keytool -genkeypair -alias tomcat -keyalg RSA -keystore /usr/local/tomcat/keystore  //创建私钥和证书文件提示输入密 ...

  9. Task05:SQL高级处理

    5.1 窗口函数 5.1.1 窗口函数概念及基本的使用方法 窗口函数也称为OLAP函数.OLAP 是OnLine AnalyticalProcessing 的简称,意思是对数据库数据进行实时分析处理. ...

  10. 面试总被问到HTTP缓存机制及原理?看完你就彻底明白了

    前言 Http 缓存机制作为 web 性能优化的重要手段,对于从事 Web 开发的同学们来说,应该是知识体系库中的一个基础环节,同时对于有志成为前端架构师的同学来说是必备的知识技能. 但是对于很多前端 ...