黑马程序员学习笔记——关于BufferedInputStream

---------------------- ASP.Net+Unity开发.Net培训、期待与您交流! ---------------------- 


BufferedInputStream,在InputStream的基础上,提供了一个缓冲区,以便于可以直接将数据写到底层的输入流,而不必直接写到底层系统中

使用基础字节流、缓冲字节流、自定义缓冲字节流copy一份文件的耗时区别:

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

public class TestMyBufferedInputStream {

	/**
	 * @param args
	 */
	public static void main(String[] args) throws IOException {
		long start1 = System.currentTimeMillis();
		copyMp3_0();
		long end1 = System.currentTimeMillis();
		System.out.println("用普通字节流copy花了" + (end1-start1) + "毫秒");
		
		long start2 = System.currentTimeMillis();
		copyMp3_1();
		long end2 = System.currentTimeMillis();
		System.out.println("用Buffered字节流copy花了" + (end2-start2) + "毫秒");
		
		long start3 = System.currentTimeMillis();
		copyMp3_2();
		long end3 = System.currentTimeMillis();
		System.out.println("用自定义Buffered字节流copy花了" + (end3-start3) + "毫秒");
		
	}

//	使用字节流拷贝
	public static void copyMp3_0() throws IOException {
		FileInputStream fis = new FileInputStream(
				"C:\\Documents and Settings\\Administrator\\桌面\\CZ\\第19天\\黑马程序员_毕向东_Java基础视频教程第19天-08-IO流(自定义装饰类).avi");
				
		FileOutputStream fos = new FileOutputStream(
				"C:\\Documents and Settings\\Administrator\\桌面\\CZ\\第19天\\a1.avi");
		System.out.println();
		int b = 0;
		while ((b=fis.read()) != -1) {
			fos.write(b);
		}
	}
	
//	使用Buffered字节流拷贝
	public static void copyMp3_1() throws IOException {
		FileInputStream fis = new FileInputStream(
				"C:\\Documents and Settings\\Administrator\\桌面\\CZ\\第19天\\黑马程序员_毕向东_Java基础视频教程第19天-08-IO流(自定义装饰类).avi");
		BufferedInputStream bis = new BufferedInputStream(fis);
				
		FileOutputStream fos = new FileOutputStream(
				"C:\\Documents and Settings\\Administrator\\桌面\\CZ\\第19天\\a2.avi");
		BufferedOutputStream bos = new BufferedOutputStream(fos);
		int b = 0;
		while ((b=bis.read()) != -1) {
			bos.write(b);
		}
//		这个flush很重要,否则会造成字节流失,但如果放while里面,又会造成用时过长
		bos.flush();
		bos.close();
		bis.close();
	}
//	使用自定义的Buffered字节流拷贝
	public static void copyMp3_2() throws IOException {
		FileInputStream fis = new FileInputStream(
				"C:\\Documents and Settings\\Administrator\\桌面\\CZ\\第19天\\黑马程序员_毕向东_Java基础视频教程第19天-08-IO流(自定义装饰类).avi");
		MyBufferedInputStream mbis = new MyBufferedInputStream(fis);
				
		FileOutputStream fos = new FileOutputStream(
				"C:\\Documents and Settings\\Administrator\\桌面\\CZ\\第19天\\a3.avi");
		BufferedOutputStream bos = new BufferedOutputStream(fos);
		
		int len = 0;
		while ((len=mbis.read()) != -1) {
			fos.write(len);
		}
	}
}

class MyBufferedInputStream {
	InputStream in = null;
	byte[] buf = new byte[1024*16];
	int result = 0;
	int pos = 0;
	int count = 0;
	public MyBufferedInputStream(InputStream in) {
		this.in = in;
	}
	
	public int read() throws IOException {
		if (0 == count) {
			count = in.read(buf);
			if (count == -1) {
				return -1;
			}
			pos = 0;
			byte b = buf[pos];
			pos++;
			count--;
//			去掉前3字节,参见注释
			return b & 255;
			
		} else if (count > 0) {
			byte b = buf[pos];
			pos++;
			count--;
//			去掉前3字节,参见注释
			return b & 0xff;
		}
		return -1;
	}
//	定义自己的关闭方法
	public void myClose() throws IOException {
		in.close();
	}
}

/*
 * 注意:在读取媒体文件的时候,由于媒体文件的内部都是以二进制形式存储的,
 * 所以有可能碰到连续的八个1情况,而这种情况,如果转为为byte形式,那就是-1
 * 所以计算机在判读read()的结束符时,就会误判
 * 
 * 解决方法,因为byte的-1,也就是11111111在转化成int时,仍然是-1,但位数变成4个字节了,也就是
 * 11111111 11111111 11111111 11111111
 * 所以我们只需要将前3个字节转化为0,只保留最后一个有效位的字节,即采用“与”运算符
 * 	 11111111 11111111 11111111 11111111
 * & 00000000 00000000 00000000 11111111
 * ——————————————————————————————————————
 *   00000000 00000000 00000000 11111111
 *   这样算换成十进制就是255了,解决了read()的判读结束问题
 *   
 *   
 * 另外,为何read()读取的4个字节的int,用write()写出去时还是1个字节的
 * 这是因为write()方法会强制转换,砍掉int的前3字节
 */
输出结果:

用普通字节流copy花了69281毫秒
用Buffered字节流copy花了1125毫秒
用自定义Buffered字节流copy花了46797毫秒


这里需要注意:read()方法的类型提示(byte->int),和write()方法的强制转化问题(int->byte)



---------------------- ASP.Net+Unity开发.Net培训、期待与您交流! ----------------------详细请查看:http://edu.csdn.net

更多 0

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值