IO基础之缓冲流的详解

Posted LayneYao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了IO基础之缓冲流的详解相关的知识,希望对你有一定的参考价值。

处理流/包装流(相对于节点流更高级):
1、隐藏了底层的节点流的差异,并对外提供了更方便的输入/输出功能,让我们只关心高级流的操作;
2、使用处理流包装节点流,程序直接操作处理流,让节点流与底层的设备做IO操作;
3、只需要关闭处理流即可。
包装流如何区分:写代码的时候,发现创建对象的时候,需要传递另一个流对象。
             new 包装流(流对象);


什么是缓冲流:
是一个包装流,目的起缓冲作用:
BufferdInputStream:字节缓冲输入流
BufferdOutputStream:字节缓冲输出流
BufferdReader:字符缓冲输入流
BufferdWriter:字符缓冲输出流


缓冲流的目的:
操作流的时候,习惯定义一个byte/char数组。
int read():每次都从磁盘文件中读取一个字节,直接操作磁盘文件性能极低。


解决方法:定义一个数组作为缓冲区
       byte[] buffer = new byte[1024];//该数组其实就是一个缓冲区
一次性从磁盘文件中读取1024个字节,如此一来,操作磁盘文件的次数少了--->性能得以提升。
缓冲流所提供的缓冲区大小是8192(1024*8)(这个可以查源码)


字节缓冲流:

/**
 * Created by Layne_Yao on 2017-7-28 上午11:01:52.
 * CSDN:http://blog.csdn.net/Jsagacity
 */
public class BufferedStreamDemo 
	public static void main(String[] args) throws Exception 
		//字节缓冲输出流
		BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("stream.txt",true));
		bos.write("i am BufferedStream!!!".getBytes());
		bos.close();

		//字节缓冲输入流
		BufferedInputStream bin = new BufferedInputStream(new FileInputStream("stream.txt"));
		byte[] buffer = new byte[1024];
		int len = -1;
		while((len = bin.read(buffer))!=-1)
			System.out.println(new String(buffer,0,len));
		
		bin.close();
	



字符缓冲流:

/**
 * Created by Layne_Yao on 2017-7-28 上午11:16:53.
 * CSDN:http://blog.csdn.net/Jsagacity
 */
public class BufferedReaderWriterDemo 

	public static void main(String[] args) throws Exception 
		// 字符缓冲输出流
		BufferedWriter out = new BufferedWriter(new FileWriter("file/stream.txt"));
		out.write("处理流/包装流(相对于节点流更高级):");
		out.newLine();
		out.write("1、隐藏了底层的节点流的差异,并对外提供了更方便的输入/输出功能,让我们只关心高级流的操作;");
		out.newLine();
		out.write("2、使用处理流包装节点流,程序直接操作处理流,让节点流与底层的设备做IO操作; ");
		out.newLine();
		out.write("3、只需要关闭处理流即可。");
		out.newLine();
		out.write("包装流如何区分:写代码的时候,发现创建对象的时候,需要传递另一个流对象。");
		out.newLine();
		out.write("new 包装流(流对象);");
		out.close();

		// 字符缓冲输入流
		BufferedReader in = new BufferedReader(new FileReader("file/stream.txt"));

//		// 传统方案:
//		char[] buffer = new char[1024];
//		int len = -1;
//		while ((len = in.read(buffer)) != -1) 
//			System.out.println(new String(buffer, 0, len));
//		
//		in.close();

		
		 String line =null;//表示读取的行
		 while((line = in.readLine())!=null)
		 System.out.println(line);
		 
		 in.close();

	


节点流和缓冲流性能对比:

操作字节和字符都习惯使用缓冲流给包装起来,提高IO性能/效率。

程序运行效率的对比:(准备一个10M左右的mp4文件)


/**
 * Created by Layne_Yao on 2017-7-28 下午1:50:48.
 * CSDN:http://blog.csdn.net/Jsagacity
 */
// 节点流和缓冲流性能对比
public class NodeStreamVSBufferedStreamDemo 

	public static void main(String[] args) throws Exception 
		File srcFile = new File("file/1蓝牙的功能与本地蓝牙.mp4");
		File destFile = new File("target/本地蓝牙.mp4");
		test4(srcFile, destFile);
	

	// 使用节点流,从磁盘文件中一个字节一个字节的读写:89251ms
	private static void test1(File srcFile, File destFile) throws Exception 
		long begin = System.currentTimeMillis();
		InputStream in = new FileInputStream(srcFile);
		OutputStream out = new FileOutputStream(destFile);
		int len = -1;
		while ((len = in.read()) != -1) 
			out.write(len);
		
		out.close();
		in.close();
		System.out.println(System.currentTimeMillis() - begin);
	

	// 使用缓冲流,从内存文件中一个字节一个字节的读写:595ms
	private static void test2(File srcFile, File destFile) throws Exception 
		long begin = System.currentTimeMillis();
		InputStream in = new BufferedInputStream(new FileInputStream(srcFile));
		OutputStream out = new BufferedOutputStream(new FileOutputStream(
				destFile));
		int len = -1;
		while ((len = in.read()) != -1) 
			out.write(len);
		
		out.close();
		in.close();
		System.out.println(System.currentTimeMillis() - begin);
	

	
	// 使用节点流,从磁盘文件中每次读写1024个字节:161ms
	private static void test3(File srcFile, File destFile) throws Exception 
		long begin = System.currentTimeMillis();
		InputStream in = new FileInputStream(srcFile);
		OutputStream out = new FileOutputStream(destFile);
		byte[] buffer = new byte[1024];
		int len = -1;
		while ((len = in.read(buffer)) != -1) 
			out.write(buffer,0,len);
		
		out.close();
		in.close();
		System.out.println(System.currentTimeMillis() - begin);
	
	
	// 使用缓冲流,从内存文件中每次读写1024个字节:54ms(最常用的方式)
		private static void test4(File srcFile, File destFile) throws Exception 
			long begin = System.currentTimeMillis();
			InputStream in = new BufferedInputStream(new FileInputStream(srcFile));
			OutputStream out = new BufferedOutputStream(new FileOutputStream(
					destFile));
			byte[] buffer = new byte[1024];
			int len = -1;
			while ((len = in.read(buffer)) != -1) 
				out.write(buffer,0,len);
			
			out.close();
			in.close();
			System.out.println(System.currentTimeMillis() - begin);
		



以上是关于IO基础之缓冲流的详解的主要内容,如果未能解决你的问题,请参考以下文章

IO流之缓冲流

Java基础—IO小结缓冲流与其它流的使用

JavaSE基础九----<IO流 >流的体系和分类,字节流,字节缓冲流

练习-Java输入输出之字节缓冲IO流之字节缓存流的高性能

练习-Java输入输出之字节缓冲IO流之字节缓存流的高性能

NIO基础1缓冲区