FileInputStream 的缓冲区怎么样?

9

我有一段代码需要读取大量(数十万)相对较小的文件(几KB),并在循环中从本地文件系统中读取。对于每个文件都创建了java.io.FileInputStream以读取内容。这个过程非常缓慢,需要很长时间。

您认为将FIS封装到java.io.BufferedInputStream中是否会有显着的差异?


4
为什么不自己尝试并测量差异呢?这是唯一了解它在您的环境中、与您的JVM等配合使用的方法。 - Péter Török
1
我在我的环境中实际测试过这个。将FIS包装到BIS中时并没有什么大的改进。 - Tomasz Błachowicz
3个回答

9

如果你在读写循环中没有使用一个合适大小的byte[]缓冲区(最新的BufferedInputStream实现使用8KB),那么它肯定会产生影响。自己试一下,不要忘记将任何OutputStream也改为BufferedOutputStream

但是,如果你已经使用了byte[]缓冲区进行了缓存,但是仍然只能获得少量的效果,那么你已经达到了硬盘和I/O控制器速度的瓶颈。


3

我非常怀疑这会有任何区别。

你的根本问题是数十万个小文件。不管你如何操作,读取它们都会让硬盘疯狂转动并且需要很长时间,你将花费99.9%的时间等待硬盘内部机械移动。

有两种方法可以解决这个问题:

  • 将数据保存在SSD上-它们的延迟要低得多(大约低五个数量级)。
  • 将数据重新排列为少量的大文件,并按顺序读取这些文件。

3
这取决于你读取数据的方式。如果你使用FileInputStream进行非常低效的读取(例如逐字节调用read()方法),那么使用BufferedInputStream可以显著提高效率。但是,如果你已经在FileInputStream中使用了合理大小的缓冲区,则切换到BufferedInputStream不会有任何影响。
由于你正在处理大量非常小的文件,很可能会有很多延迟是由于目录操作(打开、关闭)引起的,而不是实际从文件中读取字节的原因。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接