BufferedInputStream、BufferedOutputStream的效率问题
BufferedInputStream
BufferedOutputStream
public synchronized void write(byte b[], int off, int len) throws IOException {
if (len >= buf.length) {
// 如果请求长度超过输出缓冲区的大小,刷新输出缓冲区,然后直接写入数据。这样,缓冲流将无害地级联
flushBuffer();
out.write(b, off, len);
return;
}
// 如果请求长度超过缓冲区剩余位置的大小,刷新输出缓冲区
if (len > buf.length - count) {
// 注:方法中也会刷新count为0
flushBuffer();
}
// 将请求数组的请求范围的内容复制到缓冲区的剩余位置上
System.arraycopy(b, off, buf, count, len);
count += len;
}
从源码中可以看到,BufferedOutputStream在wirte时,会先判断要写的数据长度是否大于自己的缓冲区,大于缓冲区则直接flush缓冲区和数据,小于缓冲区则往缓冲区装,直到装不下了再flush缓冲区。当然,最后的write还是调用FileOutputStream#write()方法来实现,只不过用了缓冲区后减少了IO次数。
而这样做就是否在任何情况下都能提高效率呢?不是的!因为BufferedOutputStream的缓冲区大小上面是有讲究的。默认的大小是8192,即8k,在BufferedOutputStream使用默认缓冲区大小的情况下,如果一次读入的数据量(即write()方法的参数len)远远小于8K,BufferedOutputStream比FileOutputStream是有优势的,因为BufferedOutputStream明显IO次数要比FileOutputStream小,越小则BufferedOutputStream的优势越明显。经实验证实:
write()方法的参数len在4096及以下时,BufferedOutputStream是有优势的write()方法的参数len在4097-8191之间时,FilOutputSteam反而效率更高,因为在这一段2者的IO次数差不多,而BufferedOutputStream要操作2次缓冲区后才能flushwrite()方法的参数len大于等于8192时,BufferedOutputStream和FilOutputSteam效率就基本一样了
深入理解
BufferedInputStream如何缓冲IO以及InputStream中的read(byte[] b) 是否具有缓冲功能
博客主要探讨了BufferedInputStream和BufferedOutputStream。BufferedOutputStream会根据数据长度与缓冲区大小关系处理数据,使用缓冲区可减少操作次数。但并非任何情况都能提高效率,其效率与缓冲区大小和一次读入的数据量有关,实验给出不同数据量下两者的效率对比。
1393

被折叠的 条评论
为什么被折叠?



