BufferedInputStream有什么作用呢?感觉意义不大啊

txtdown0909 2013-07-14 12:47:33
直接上代码:

public class InputStreamTest {
private static final String FILENAME="E:\\电影\\[高清电影]阿甘正传.1994.美国.中文字幕.1280x720.rmvb";
public static void main(String[] args) throws IOException {
long l1 = readByBufferedInputStream();
long l2 = readByInputStream();
System.out.println("通过BufferedInputStream读取用时:"+l1+";通过InputStream读取用时:"+l2);
}

public static long readByInputStream() throws IOException {
InputStream in=new FileInputStream(FILENAME);
byte[] b=new byte[8192];
int l=0;
long start=System.currentTimeMillis();
while(in.read(b,0,8192)!=-1){
}
long end=System.currentTimeMillis();
return end-start;
}

public static long readByBufferedInputStream() throws IOException {
BufferedInputStream in=new BufferedInputStream(new FileInputStream(FILENAME));
byte[] b=new byte[8192];
int l=0;
long start=System.currentTimeMillis();
while(in.read(b,0,8192)!=-1){
}
long end=System.currentTimeMillis();
return end-start;
}
}

以上代码,一共有两个方法,第一个就是用InputStream读取数据的,第二个就是用BufferedInputStream读取数据的,其他的代码都一样,至于缓冲数组大小为8192是因为BufferedInputStream里面的默认数组大小就是8192的。我那个文件大小是1.46G。

但是运行结果很令我诧异:
通过BufferedInputStream读取用时:705;通过InputStream读取用时:669
通过BufferedInputStream读取用时:727;通过InputStream读取用时:690
通过BufferedInputStream读取用时:721;通过InputStream读取用时:689


但是结果BufferedInputStream用时高于InputStream。虽然差的不多,但是在我映像中,BufferedInputStream应该明显小于InputStream的啊。
这个是为什么呢?BufferedInputStream的缓冲功能又是在什么时候用的呢?
个人所学浅薄,如有错误,不吝赐教!
...全文
33351 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
wangjun5159 2016-04-05
  • 打赏
  • 举报
回复
引用 12 楼 zddddz 的回复:
[quote=引用 8 楼 wangjun5159 的回复:] 没有缓存区,那么每read一次,就会发送一次IO操作; 有缓存区,第一次read时,会一下读取x个字节放入缓存区,然后后续的read都会从缓存中读取,当read到缓存区末尾时,会再次读取x个字节放入缓存区。 很明显,第二种方式,会减少IO操作,效率更高,缺点就是,内存占用的多。
你这里的x是如何定义的?是指buffer size的大小吗? 如果是的话,那么当两者一次读入的字节数一样多的话,那么BufferedInputStream应该永远比InputStream慢,因为它多了一个缓冲区操作。但是为什么将buffersize设置为256k的时候,BufferedInputStream又明显快了呢?[/quote] 是的,x指buffer size的大小。 上述程序中,使用的是fileinputstream,也是一次读取多个字节,跟bufferedinputstream的缓存一个作用。 所以,这两个方法的耗时应该是差不多的。如果将fileinputstream由read(byte[] b, int off, int len) 改为read(),耗时差异就很明显了!
zddddz 2016-03-15
  • 打赏
  • 举报
回复
引用 8 楼 wangjun5159 的回复:
没有缓存区,那么每read一次,就会发送一次IO操作; 有缓存区,第一次read时,会一下读取x个字节放入缓存区,然后后续的read都会从缓存中读取,当read到缓存区末尾时,会再次读取x个字节放入缓存区。 很明显,第二种方式,会减少IO操作,效率更高,缺点就是,内存占用的多。
你这里的x是如何定义的?是指buffer size的大小吗? 如果是的话,那么当两者一次读入的字节数一样多的话,那么BufferedInputStream应该永远比InputStream慢,因为它多了一个缓冲区操作。但是为什么将buffersize设置为256k的时候,BufferedInputStream又明显快了呢?
zddddz 2016-03-15
  • 打赏
  • 举报
回复
引用 10 楼 kakalotto 的回复:
你这里,通过BufferedInputStream读取用的时间比通过InputStream读取用时时间长,是消耗在你从缓冲区里读取数据的时间。用了BufferedInputStream后你每次读取都是从缓冲区里拷贝数据,在后你再读,缓冲区没东西了就调IO从数据源读到缓冲区,然后你再从缓冲区读。为什么会这样呢,因为你自己建立的数组大小和缓冲区大小一样,根本就没起到缓冲作用。 当你程序的数组小于缓冲区的大小的时候才会起到缓冲作用。比如是byte[] b=new byte[2048];,你要读的数据是1G,那么你要调512次IO,假设一次1s,就512s,但如果用BufferedInputStream,你每从缓冲区读取4(8192/2048=4)次才调用一次IO(假设访问内存一次0.1s),总共要128次,就128s,加上总的从缓冲区拷贝数据的时间(512*0.1=51.2s),128+51.2=179.2。 这里用0.1s和1s来体现IO很耗时
你这个说法和上面的测试刚好相反,上面测试8K和256K时,BufferedInputStream明显速度更快。怎么回事?
zddddz 2016-03-15
  • 打赏
  • 举报
回复
引用 3 楼 longtian1213 的回复:
不带缓冲的操作,每读一个字节就要写入一个字节,由于涉及磁盘的IO操作相比内存的操作要慢很多,所以不带缓冲的流效率很低。带缓冲的流,可以一次读很多字节,但不向磁盘中写入,只是先放到内存里。等凑够了缓冲区大小的时候一次性写入磁盘,这种方式可以减少磁盘操作次数,速度就会提高很多!这就是两者的区别
楼主的代码好像没有写入的操作。这个解释有些牵强。
kakalotto 2015-10-22
  • 打赏
  • 举报
回复
你这里,通过BufferedInputStream读取用的时间比通过InputStream读取用时时间长,是消耗在你从缓冲区里读取数据的时间。用了BufferedInputStream后你每次读取都是从缓冲区里拷贝数据,在后你再读,缓冲区没东西了就调IO从数据源读到缓冲区,然后你再从缓冲区读。为什么会这样呢,因为你自己建立的数组大小和缓冲区大小一样,根本就没起到缓冲作用。
当你程序的数组小于缓冲区的大小的时候才会起到缓冲作用。比如是byte[] b=new byte[2048];,你要读的数据是1G,那么你要调512次IO,假设一次1s,就512s,但如果用BufferedInputStream,你每从缓冲区读取4(8192/2048=4)次才调用一次IO(假设访问内存一次0.1s),总共要128次,就128s,加上总的从缓冲区拷贝数据的时间(512*0.1=51.2s),128+51.2=179.2。
这里用0.1s和1s来体现IO很耗时
one way 2015-10-14
  • 打赏
  • 举报
回复
涨姿势了,学到了,谢谢各路大神
wangjun5159 2015-10-10
  • 打赏
  • 举报
回复 1
没有缓存区,那么每read一次,就会发送一次IO操作; 有缓存区,第一次read时,会一下读取x个字节放入缓存区,然后后续的read都会从缓存中读取,当read到缓存区末尾时,会再次读取x个字节放入缓存区。 很明显,第二种方式,会减少IO操作,效率更高,缺点就是,内存占用的多。
cnmm22 2015-03-14
  • 打赏
  • 举报
回复
上面是8K
改到800K后

通过BufferedInputStream读取用时:35095;通过InputStream读取用时:57786
cnmm22 2015-03-14
  • 打赏
  • 举报
回复
通过BufferedInputStream读取用时:51844;通过InputStream读取用时:52941


读了3G压缩包。
sca4441479 2013-07-31
  • 打赏
  • 举报
回复
3楼+1; BUFFERED缓冲区,是综合下来效率高,而不是读是速度比谁快。
xiong1250 2013-07-31
  • 打赏
  • 举报
回复
效率问题啊,前面讲的很好了,字符流上带缓冲效果更明显
S117 2013-07-14
  • 打赏
  • 举报
回复
不带缓冲的操作,每读一个字节就要写入一个字节,由于涉及磁盘的IO操作相比内存的操作要慢很多,所以不带缓冲的流效率很低。带缓冲的流,可以一次读很多字节,但不向磁盘中写入,只是先放到内存里。等凑够了缓冲区大小的时候一次性写入磁盘,这种方式可以减少磁盘操作次数,速度就会提高很多!这就是两者的区别
iihero_ 2013-07-14
  • 打赏
  • 举报
回复 1
另外,在用bufferedinputstream时,可以对buffersize参数调整一下,设成256K试试,效果肯定不一样. 当它的buffer设成256K时, fileinputstream设成8k时,前者还是要快一些的. 256 * 1024, 通过BufferedInputStream读取用时:2135; 通过InputStream (8K)读取用时:3353 两者都为256K时,通过BufferedInputStream读取用时:2220;通过InputStream读取用时:2319 我的机器,RAM:8G, x64 win7.
iihero_ 2013-07-14
  • 打赏
  • 举报
回复 1
可以参照:MappedByteBuffer, 这个对于读取大文件速度占优势.

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧