File类与常用IO流第八章——缓冲流
第八章、缓冲流
缓冲流概述
缓冲流,也叫高效流,是对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 缓冲区的有效字节数
使用步骤
创建FileOutputStream 对象,构造方法中绑定要输出的目的地;
创建BufferedOutputStream 对象,构造方法中传递 FileOutputStream 对象,提高FileOutputStream对象的效率;
使用BufferedOutputStream 对象中的方法write,把数据写入到内部缓冲区中;
使用BufferedOutStream 对象中的方法flush,把内部缓冲区的数据,刷新到文件中;
释放资源(会先调用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()
使用步骤
创建FileInputStream 对象,构造方法中绑定要读取的目的地;
创建BufferedInputStream 对象,构造方法中传递FileInputStream对象;
使用BufferedInputStream对象中的方法read,读取文件;
释放资源。
代码片段【下面两个代码片段是一样的,只是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 使用步骤
创建字符缓冲输出流对象,构造方法中传递字符输出流;
调用字符输出流中的方法write,把数据写入到内存缓冲区中;
调用字符缓冲输出流中的方法flush,把内存缓冲区中的数据,刷新到文件中;
释放资源
代码片段:
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。
使用步骤:
创建字符缓冲输入流对象,构造方法中传递字符输入流;
使用字符缓冲输入流对象中的方法read/readLine读取文本;
释放资源。
代码片段
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流第八章——缓冲流的更多相关文章
- File类与常用IO流第四章——IO字节流
一切文件在存储时,都是以二进制数字的形式保存的,都是一个一个字节.无论使用什么样的流对象,底层传输的始终是二进制数据. 字节输出流 OutputStream java.io.OutputStream ...
- File类与常用IO流第一章File类
第一章:File类 一.1个重点单词: file:文件:directory:文件夹/目录:path:路径(绝对路径:absolutePath) 二.4个静态成员变量: 1.static String ...
- File类与常用IO流第七章——Properties集合
Properties概述 java.util.Properties extends Hashtable<k,v> implements Map<k,v> Properties类 ...
- File类与常用IO流第二章过滤器
在第一章中,有一个练习使用递归搜索文件 1 public static void main(String[] args) { 2 File f=new File("E:\\aaa" ...
- File类与常用IO流第九章——转换流
第九章.转换流 字节编码和字符集 编码:按照某种规则将字符以二进制存储到计算机中. 解码:将存储在计算机中的二进制数按照某种规则解析显示出来. 字符编码:Character Encoding ,就是一 ...
- File类与常用IO流第十一章——打印流
第十一章.打印流 概述:java.io.PrintStream extends OutputStream,为其他输出流添加了功能,使题目能够方便的打印各种数据值表示形式. 特点: 只负责数据的输出,不 ...
- File类与常用IO流第十章——序列化流
第十章.序列化流 序列化流和反序列化流概述 序列化:用一个字节序列表示一个对象,该字节序列包含该对象的数据.对象的类型和对象中存储的属性等等信息.字节序列写出到文件后,相当于文件中持久保存了一个对象的 ...
- File类与常用IO流第五章——IO字符流
字符流,只能操作文本文件,不能操作图片.视频等非文本文件 字符输入流 java.io.Reader 字符输入流中一些共性的成员方法 int read():读取单个字符并返回. int read(cha ...
- File类与常用IO流第六章——使用try...catch...finally处理流中的异常
在JDK1.7之前: 1 package com.itheima.demo06.trycatch; 2 3 import java.io.FileWriter; 4 import java.io.IO ...
随机推荐
- CVPR2020论文解读:3D Object Detection三维目标检测
CVPR2020论文解读:3D Object Detection三维目标检测 PV-RCNN:Point-Voxel Feature Se tAbstraction for 3D Object Det ...
- Kubeedge Edged概述
Kubeedge Edged概述 Overview EdgeD是管理节点生命周期的边缘节点模块.它可以帮助用户在边缘节点上部署容器化的工作负载或应用程序.这些工作负载可以执行任何操作,从简单的远程遥测 ...
- 使用Nucleus SE实时操作系统
使用Nucleus SE实时操作系统 Using the Nucleus SE real-time operating system 到目前为止,在本系列文章中,我们详细介绍了Nucleus SE提供 ...
- Git_远程仓库fork操作
fork操作:当选择 fork,相当于自己有了一份原项目的拷贝,当然这个拷贝只是针对当时的项目文件,如果后续原项目文件发生改变,你必须通过其他的方式去同步. 使用场景:一般来说,不需要使用 fork ...
- 2、java数据结构和算法:单链表: 反转,逆序打印, 合并二个有序链表,获取倒数第n个节点, 链表的有序插入
什么也不说, 直接上代码: 功能点有: 1, 获取尾结点 2, 添加(添加节点到链表的最后面) 3, 添加(根据节点的no(排名)的大小, 有序添加) 4, 单向链表的 遍历 5, 链表的长度 6, ...
- 牛客网论坛最具争议的Java面试成神笔记,牛客网下载量已突破十万
程序员内部一直流传这一句话: 面试看牛客 刷题看力扣 牛客网作为国内最牛的程序员面试网站,一直在程序员内部颇负盛名,其中用户更是卧虎藏龙! 有国内一线大厂的企业招聘 还有一些低调的互联网大牛实力就和天 ...
- 日常Bug排查-Nginx重复请求?
日常Bug排查-Nginx重复请求? 前言 日常Bug排查系列都是一些简单Bug排查,笔者将在这里介绍一些排查Bug的简单技巧,其中不乏一些看起来很低级但很容易犯的问题. 问题现场 有一天运维突然找到 ...
- 七、SSL加密网站(待解决)
keytool -genkeypair -alias tomcat -keyalg RSA -keystore /usr/local/tomcat/keystore //创建私钥和证书文件提示输入密 ...
- Task05:SQL高级处理
5.1 窗口函数 5.1.1 窗口函数概念及基本的使用方法 窗口函数也称为OLAP函数.OLAP 是OnLine AnalyticalProcessing 的简称,意思是对数据库数据进行实时分析处理. ...
- 面试总被问到HTTP缓存机制及原理?看完你就彻底明白了
前言 Http 缓存机制作为 web 性能优化的重要手段,对于从事 Web 开发的同学们来说,应该是知识体系库中的一个基础环节,同时对于有志成为前端架构师的同学来说是必备的知识技能. 但是对于很多前端 ...