Java输入输出流四:字节流之缓冲流(BufferedInputStream&BufferedOutputStream)

一:缓冲流简介:为什么能提升效率

● 原先没有缓冲流的情况:通过FileInputStream(文件输入流)和FileOutputStream(文件输出流)可知,在文件拷贝的时候,其文件数据的流转顺序为:

       文件→FileInputStream→字节数组→FileOutputStream→文件Copy;

●使用缓冲流的情况: 

       文件→FileInputStream→字节数组→缓冲区→FileOutputStream→文件Copy;

●缓冲流为什么能够提高读写速度:(有几种说法如下,有点笼统

       (1)文件的读写包括:文件的I/O和其他操作,没有缓冲区时,I/O和其他操作都是CPU的工作(CPU采用DMA的方式去执行I/O操作);设了缓冲区后,CPU 将I/O操作交给专门的DMA控制器去做,当缓冲区填满后,DMA控制器会通知CPU,以让其完成其他操作;DMA控制器比CPU更善于做I/O与内存数据交换,从而提升效率。

       (2)文件读写是需要和硬件打交道的,每次读写就是一次I/O操作,而io操作是很费时的。而其中,又包括读和写;没有缓冲区时,是读一点(byte字节数组)写一点;有缓冲区后,是读一点,往缓冲区里存一点,如此多次读,直到将缓冲区存满,缓冲区满了后,再将这些数据一次性地写入到文件中。所以,可以这样认为,缓冲区减少了写的次数,从而提升效率。

       (2.1)通过本篇博客的例子中,缓冲流的使用。可以看出,读的时候,还是一个字节数组一个字节数组的读,把读到的数据存到缓冲区中,然后写的时候,看起来也是一个字节数组一个字节数组的写,好像并没有看到缓冲区在哪儿,,,,,好吧,为了说服自己,暂时认为缓冲区对用户(在程序代码中)不可见吧


二:缓冲流属性和方法简介

BufferedInputStream:缓冲输入流

属性:

构造方法:

        缓冲输入流的构建需要传入一个文件输入流作为参数

常用方法:

……………………………………………………

BufferedOutputStream:缓冲输出流

属性:

构造方法:

        缓冲输出流的构建需要传入一个文件输出流作为参数

常用方法:

注:close()方法会强制清空缓冲区内容,这也会把缓冲区中的内容写入到文件中。


三:缓冲流在文件复制中的示例

(1)使用缓冲流复制文件:使用“#######”标识的语句为缓冲流新增内容;

(2)为了使代码简洁,也可写成这样:

public class FileOutputDemo2 {

	public static void main(String[] args) {
		// 文件拷贝:图片文件的复制粘贴,读取和写入
		// (1)创建输入流对象,输出对象
		FileInputStream fis;
		FileOutputStream fos;
		BufferedInputStream bis;
		BufferedOutputStream bos;
		try {
			// (2)实例化输入流对象指向待复制文件;实例化输出对象,参数为复制后文件的全路径;
			fis = new FileInputStream("video.mp4");
			// (2.1)构造缓冲输入流
			bis = new BufferedInputStream(fis);     // 缓冲输入流#######
			fos = new FileOutputStream("videoCopy.mp4");
			// (2.2)构造缓冲输出流
			bos = new BufferedOutputStream(fos);    // 缓冲输出流#######
			// (3)n存放读方法的返回值,如果为-1代表已经读到文件末尾了;
			int n = 0;
			// (4)定义一个字节数组,存放读取到的数据;这个数组得大一点;
			byte[] b = new byte[1024];
			
			long startTime = System.currentTimeMillis();   // 对比运行时间用  #######
			
			// (5)读取内容,并同时将读取到的内容写出来;这儿是每读1024个字节就写一下,即读一点写一点,直到全部复制完;
			// (5.1)调用缓冲输入流的read()方法
			while((n = bis.read(b))!= -1){  // 缓冲流的read方法和write方法和文件流的并无二致#######
			// (5.2)调用缓冲输出流的write()方法
				bos.write(b,0,n); // 将读取到的内容写到fos这个文件流对象对应的文件中去;
			}
			// (6)关闭输入流、输出流;
			bos.flush();
			long endTime = System.currentTimeMillis();// 对比运行时间用  #######
			System.out.println(endTime - startTime);
			fis.close();
			fos.close();
			bis.close();
			bos.close();
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e){  // 注:这几文件的读写,IOException是必须抛出的,当成常识记住就行…
			e.printStackTrace();
		}
	}

}

其运行时间为:

上篇博客中未使用缓冲流复制文件时:

(下面代码可以不用看和上篇博客内容一样)

public class BufferedDemo1 {

	public static void main(String[] args) {
		// 文件拷贝:图片文件的复制粘贴,读取和写入
		// (1)创建输入流对象,输出对象
		FileInputStream fis;
		FileOutputStream fos;
		BufferedInputStream bis;
		BufferedOutputStream bos;
		try {
			// (2)实例化输入流对象指向待复制文件;实例化输出对象,参数为复制后文件的全路径;
			fis = new FileInputStream("video.mp4");
			//bis = new BufferedInputStream(fis);     // 缓冲输入流
			fos = new FileOutputStream("videoCopy.mp4");
			//bos = new BufferedOutputStream(fos);    // 缓冲输出流
			// (3)n存放读方法的返回值,如果为-1代表已经读到文件末尾了;
			int n = 0;
			// (4)定义一个字节数组,存放读取到的数据;这个数组得大一点;
			byte[] b = new byte[1024];
			
			long startTime = System.currentTimeMillis();
			
			// (5)读取内容,并同时将读取到的内容写出来;这儿是每读1024个字节就写一下,即读一点写一点,直到全部复制完;
			while((n = fis.read(b))!= -1){
				fos.write(b,0,n); // 将读取到的内容写到fos这个文件流对象对应的文件中去;
			}
			// (6)关闭输入流、输出流;
			//bos.flush();
			long endTime = System.currentTimeMillis();
			System.out.println(endTime - startTime);
			fis.close();
			fos.close();
			//bis.close();
			//bos.close();
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e){  // 注:这几文件的读写,IOException是必须抛出的,当成常识记住就行…
			e.printStackTrace();
		}
	}
}

运行时间:可以发现,缓冲流对效率的提升还是挺明显的。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值