缓冲流

缓冲流能够高效的读写,它是在基本的流对象基础之上创建而来的,相当于是对基本流对象的一种增强。

java 和 流 缓冲区 java的缓冲流_构造方法

 

▶  概述

缓冲流也叫高效流,是对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方法刷新数据,第四步可以省略)

java 和 流 缓冲区 java的缓冲流_输入流_02

 

▶  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)释放资源

java 和 流 缓冲区 java的缓冲流_java 和 流 缓冲区_03

java 和 流 缓冲区 java的缓冲流_java 和 流 缓冲区_04

 

▶  效率测试

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)释放资源

java 和 流 缓冲区 java的缓冲流_输入流_05

 

▶  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)释放资源

java 和 流 缓冲区 java的缓冲流_输入流_06

发现以上读取是一个重复的过程,所以可以使用循环优化,不知道文件中有多少行数据所以使用 while 循环,while 的结束条件是读取到 null 结束

java 和 流 缓冲区 java的缓冲流_java 和 流 缓冲区_07

 

▶  练习 : 对文本的内容进行排序

要求:按照(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)释放资源

 

java 和 流 缓冲区 java的缓冲流_java 和 流 缓冲区_08

如果上面的代码输出的 out.txt 出现乱码则可以用下面的代码解决这个乱码问题 。

java 和 流 缓冲区 java的缓冲流_输入流_09