缓冲流
缓冲流能够高效的读写,它是在基本的流对象基础之上创建而来的,相当于是对基本流对象的一种增强。
编辑
▶ 概述
缓冲流也叫高效流,是对4个基本的 FileXxx 流的增强,所以也是4个流,按照数据类型分为:
(1)字节缓冲流 :BufferedInputStream ,BufferedOutputStream
(2)字符缓冲流 :BufferedReader ,BufferedWriter
缓冲流的基本原理:在创建流对象的时候会创建一个内置的默认大小的缓冲区数组,通过缓冲区读写,减少系统IO次数,从而提高效率。
▶ BufferedOutputStream --- 字节缓冲输出流
java.io.BufferedOutputStream extends OutputStream
✔ BufferedOutputStream 继承自父类的共性成员方法:
--- public void close() 关闭此输出流并释放与此流相关联的任何系统资源
--- public void flush() 刷新此输出流并强制任何缓冲的输出字节被写出
--- public void write( byte[ ] b ) 将 b.length 字节从指定的字节数组写入此输出流
--- public void write( byte[ ] b ,int off ,int len ) 从指定的字节数组写入 len 字节,从偏移量 off 开始输出到此输出流
--- public abstract void write( int b ) 将指定的字节输出
✔ 构造方法:
BufferedOutputStream( OutputStream out ) 创建一个新的缓冲输出流,以将数据写入指定的底层输出流
BufferedOutputStream( OutputStream out ,int size ) 创建一个新的缓冲输出流,以将指定
参数:
OutputStream out -- 字节输出流,可以传递FileOutputStream,缓冲流会给FileOutputStream增加一个缓冲区,提高FileOutputStream的写入效率
int size -- 指定缓冲流内部缓冲区的大小,不指定则默认
✔ 使用步骤:
(1)创建FileOutputStream对象,构造方法中绑定要输出的目的地
(2)创建BufferedOutputStream对象,构造方法中传递FileOutputStream对象,提高FileOutputStream对象效率
(3)使用BufferedOutputStream对象中的方法write把数据写入到内部缓冲区中
(4)使用BufferedOutputStream对象中的方法flush把内部缓冲区中的数据刷新到文件中
(5)释放资源(会先调用flush方法刷新数据,第四步可以省略)
编辑
▶ BufferedInputStream --- 字节缓冲输入流
java.io.BufferedInputStream extends InputStream
✔ BufferedInputStream 继承自父类的共性成员方法:
--- int read() 从输入流中读取数据的下一个字节
--- int read( byte[ ] b ) 从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中
--- void close() 关闭此输入流并释放与该流关联的所有系统资源
✔ 构造方法:
BufferedInputStream( InputStream in ) 创建一个BufferedInputStream并保存其参数,即输入流in以便将来使用
BufferedInputStream( InputStream in ,int size ) 创建具有指定缓冲区大小的 BufferedInputStream并保存其参数,即输入流in
参数:
InputStream in -- 字节输入流,可以传递FileInputStream对象,缓冲流会给FileInputStream对象增加一个缓冲区,提高FileInputStream的读取效率
int size -- 指定缓冲流内部缓冲区的大小,不指定则默认
✔ 使用步骤:
(1)创建FileInputStream对象,构造方法中要绑定要读取的数据源
(2)创建BufferedInputStream对象,构造方法中传递FileInputStream对象,提高FileInputStream对象的读取效率
(3)使用BufferedInputStream对象中的方法read读取文件
(4)释放资源
编辑
编辑
▶ 效率测试
import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; /* 文件复制练习:一读一写 明确: 数据源 -- E:\code\JAVA\load\33.jpg 数据的目的地 -- E:\code\JAVA\load\aaa\4.jpg 文件复制的步骤: 1.创建字节缓冲输入流对象,构造方法中传递字节输入流 2.创建字节缓冲输出流对象,构造方法中传递字节输出流 3.使用字节缓冲输入流对象中的方法read,读取文件 4.使用字节缓冲输出流中的方法write把读取的数据写入到内部缓冲区中 5.释放资源(会先把缓冲区中的数据刷新到文件中) 文件大小:128,636 字节 一次读写一个字节:39毫秒 使用数组缓冲读取多个字节再写入多个字节:1毫秒 */ public class Demo07 { public static void main(String[] args) throws IOException { long s = System.currentTimeMillis() ; FileInputStream fis = new FileInputStream("E:\\code\\JAVA\\upload\\33.jpg") ; BufferedInputStream bis = new BufferedInputStream(fis); FileOutputStream fos = new FileOutputStream("E:\\code\\JAVA\\upload\\aaa\\4.jpg"); BufferedOutputStream bos = new BufferedOutputStream(fos); // 每次读单个字节,输出:复制文件共耗时:39毫秒 int len = 0; while((len=bis.read())!=-1) { bos.write(len); } // 每次读一个数组,输出:复制文件共耗时:1毫秒 byte[] bytes = new byte[1024]; int len1 = 0; while((len1 = bis.read(bytes))!=-1) { bos.write(bytes,0,len1); } bos.close(); bis.close(); long e = System.currentTimeMillis(); System.out.println("复制文件共耗时:"+(e-s)+"毫秒"); } }
▶ BufferedWriter --- 字符缓冲输出流
java.io.BufferedWriter extends Writer
✔ BufferedWriter 继承自父类的共性成员方法:
--- void write( int c ) :写入单个字符
--- void write( char[ ] cbuf ) :写入字符数组
--- abstract void write( char[ ] cbuf,int off,int len ) :写入字符数组的某一部分,off是数组的开始索引,len是写的字符的个数
--- void write( String str ) :写入字符串
--- void write( String str,int off,int len ) :写入字符串的某一部分,off是字符串的开始索引,len是写的字符个数
--- void flush() :刷新该流的缓冲
--- void close() :关闭此流,但要先刷新它
✔ 构造方法:
BufferedWriter( Writer out ) 创建一个使用默认大小输出缓冲区的缓冲字符输出流
BufferedWriter( Writer out ,int sz ) 创建一个使用给定大小输出缓冲区的新缓冲字符输出流
参数:
Writer out -- 字符输出流 ,可以传递 FileWriter,缓冲流会给 FileWriter增加一个缓冲区提高写入效率
int sz -- 指定缓冲区的大小,不写默认大小
✔ 特有成员方法:
--- void newLine() 写入一个行分隔符,会根据不同的操作系统获取不同的行分隔符
✔ 使用步骤:
(1)创建字符缓冲输出流对象,构造方法中传递字符输出流
(2)调用字符缓冲输出流中的方法write,把数据写入到内存缓冲区中
(3)调用字符缓冲输出流中的方法flush,把内存缓冲区中的数据刷新到文件中
(4)释放资源
编辑
▶ BufferedReader --- 字符缓冲输入流
java.io.BufferedReader extends Reader
✔ BufferedReader 继承自父类的共性成员方法:
--- int read() :读取单个字符并返回
--- int read(char[ ] cbuf ) :一次读取多个字符,将字符读入数组
--- void close() :关闭该流并释放与之关联的所有资源
✔ 构造方法:
BufferedReader( Reader in ) 创建一个使用默认大小输入缓冲区的缓冲字符输入流
BufferedReader( Reader in ,int sz ) 创建一个使用指定大小输入缓冲区的缓冲字符输入流
参数:
Reader in -- 字符输出流 ,可以传递 FileWriter,缓冲流会给 FileWriter增加一个缓冲区提高写入效率
int sz -- 指定缓冲区的大小,不写则默认大小
✔ 特有成员方法:
--- String readLine() 读取一个文本行,读取一行数据
行的终止符号:通过下列字符之一即可认为某行已终止 ,“ 换行 ( \n )” 、“ 回车( \r )” 或者回车后直接跟着换行( \r\n )
返回值:包含改行内容的字符串,不包含任何行终止符,如果已到达流末尾则返回 null
✔ 使用步骤:
(1)创建字符缓冲输入流对象,构造方法中传递字符输入流
(2)使用字符缓冲输入流对象中的方法 read / readLine 读取文本
(3)释放资源
编辑
发现以上读取是一个重复的过程,所以可以使用循环优化,不知道文件中有多少行数据所以使用 while 循环,while 的结束条件是读取到 null 结束
编辑
▶ 练习 : 对文本的内容进行排序
要求:按照(1,2,3,...... )顺序进行排序
分析:
(1)创建一个 HashMap 集合对象,key 存储每行文本的序号(1,2,3,...),value 存储每行的文本
(2)创建字符缓冲输入流对象,构造方法中绑定字符输入流
(3)创建字符缓冲输出流对象,构造方法中绑定字符输出流
(4)使用字符缓冲输入流中的方法 readLine 逐行读取文本
(5)对读取到的文本进行切割获取行中的序号和文本内容
(6)把切割好的序号和文本内容存储到 HashMap 集合中( key 序号是有序的,会自动排序1,2,3,4,....)
(7)遍历 HashMap 集合,获取每一个键值对
(8)把每一个键值对拼接成一个文本行
(9)把拼接好的文本使用字符缓冲输出流中的方法 write 写入到文件中
(10)释放资源
编辑
如果上面的代码输出的 out.txt 出现乱码则可以用下面的代码解决这个乱码问题 。
编辑