【问题标题】:Increase Internal Buffer Size Used by Java FileInputStream增加 Java FileInputStream 使用的内部缓冲区大小
【发布时间】:2011-01-26 03:43:10
【问题描述】:

FileInputStream 上调用read(byte[]) 时,读取大小始终为8k,即使byte[] 呈指数级增长。

如何提高每次调用返回的最大读取量?

请不要提出仅仅掩盖FileInputStream限制的方法。


更新:似乎没有真正的解决方案。但是,对于 1G 文件,我计算出系统上的方法调用开销约为 226uS。可以肯定地说,这不会以任何实际方式影响性能。

【问题讨论】:

标签: java stream io inputstream fileinputstream


【解决方案1】:

将它包装在一个 BufferedInputStream 中,它允许您指定缓冲区大小。

【讨论】:

  • 这不就是把fileinputstream的读取方法包装在一个while循环里吗?
  • 底层 FileInputStream 将每 8k 发出一个 OS read() 是否有助于这一事实?好吧,也许 OS 的 I/O 子系统会将几个连续的读取批处理在一起,但是 Java 到 OS 调用的开销仍然存在。
【解决方案2】:

您可以尝试使用 NIO 对文件进行内存映射,但我不确定 8K 的问题是什么。 您可以将 8K 复制到更大的数组中,也可以使用返回的长度来调用

public int read(byte[] b,
                int off,
                int len)
         throws IOException

off 是上次读取的返回值。

【讨论】:

  • 以 8K 读取 1G 文件是 2^17 次方法调用。我有兴趣以较低的 JVM 开销进行基准测试。
  • 在这种情况下,FileChannel.map 可能更适合您,尽管我认为这些调用没有问题。无论如何,JVM 都会优化掉大部分开销。
  • OS/FS 也负责自己的预读缓冲区。因此,一旦它步入正轨,系统调用应该相对便宜。 (例如,IO 读取本身的系统调用开销是多少?)
  • 是什么让你相信 JVM 会优化它?如果是这种情况,它应该在可能的情况下执行大于 8k 的读取。
  • 开销约为 226uS ... 不多
【解决方案3】:

您看到的每次读取的大小可能是操作系统本身使用的缓冲区大小。因此,您可能必须在操作系统级别进行更改。你如何做到这一点将取决于系统。您可以在创建文件系统时指定块大小。传统上这对于 Unix 文件系统是可行的。尽管具有讽刺意味的是,我认为该功能用于为预计有许多小文件的文件系统提供更小的块。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-08-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多