---------------------- 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