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 ...
随机推荐
- PVD与CVD性能比较
PVD与CVD性能比较 CVD定义: 通过气态物质的化学反应在衬底上淀积一层薄膜材料的过程. CVD技术特点: 具有淀积温度低.薄膜成分和厚度易于控制.均匀性和重复性好.台阶覆盖优良.适用范围广.设备 ...
- ResNet网络的训练和预测
ResNet网络的训练和预测 简介 Introduction 图像分类与CNN 图像分类 是指将图像信息中所反映的不同特征,把不同类别的目标区分开来的图像处理方法,是计算机视觉中其他任务,比如目标检测 ...
- GPU上的快速光谱图分区
GPU上的快速光谱图分区 图形是用于对物理,生物,社会和信息系统中许多类型的关系和过程进行建模的数学结构.用于解决各种高性能计算和数据分析问题.对于网络分析,基因组学,社交网络分析和其他领域,大规模图 ...
- GoLang:通过url将值从view层(.tpl)传递到controller层
beego框架 1.定义路由: beego.Router("/UpdateState/:statename/:id", &controllers.ContentContro ...
- Nginx为什么能快到根本停不下来?
Nginx 以其高性能,稳定性,丰富的功能,简单的配置和低资源消耗而闻名.本文从底层原理分析 Nginx 为什么这么快! Nginx 的进程模型 Nginx 服务器,正常运行过程中: 多进程:一个 M ...
- WPF添加外边框,添加外边框虚线
<Border Background="LightBlue" BorderBrush="Black" BorderThickness="2&q ...
- 解析 Nebula Graph 子图设计及实践
本文首发于 Nebula Graph 公众号 NebulaGraphCommunity,Follow 看大厂图数据库技术实践. 前言 在先前的 Query Engine 源码解析中,我们介绍了 2.0 ...
- 『无为则无心』Python基础 — 12、Python运算符详细介绍
目录 1.表达式介绍 2.运算符 (1)运算符的分类 (2)算数运算符 (3)赋值运算符 (4)复合赋值运算符 (5)比较运算符 3.逻辑运算符 拓展1:数字之间的逻辑运算 拓展2:Python中逻辑 ...
- javascript之一切都是对象
在学习的过程中,我们常常能听到这样一句话:一切皆是对象.那么这句话该如何理解呢?首先,我们要明确对象的概念.要明白除了基本数据类型都是对象. typeof操作符是大家经常使用的,我们常用它来检测给定变 ...
- 22、lnmp_nginx反向代理(负载均衡)、高可用
负载均衡,根据ip和端口号找到相应的web服务器站点(即端口区分): 22.1.nginx的负载均衡: 1.介绍: 网站的访问量越来越大,服务器的服务模式也得进行相应的升级,比如分离出数据库服务器.分 ...