gpt4 book ai didi

java - 如何在 Java 中实现缓冲/批处理 FileChannel?

转载 作者:行者123 更新时间:2023-12-01 17:29:18 26 4
gpt4 key购买 nike

这看起来并不简单,特别是对于读/写缓冲的 FileChannel。是否有任何开源实现可以作为我的实现的基础?

<小时/>

为那些不明白的人澄清一下:

FileChannel 在操作系统级别进行缓冲,我想在 Java 级别进行缓冲。阅读此处了解:FileChannel#force and buffering

<小时/>

@Peter 我想从快速消息流将一个大文件写入磁盘。缓冲和批处理是可行的方法。所以我想用Java批处理,然后调用FileChannel.write。

最佳答案

我建议使用 BufferedOutputStream 包装 FileOutputStream。我不相信您会通过使用 ByteBufferFileChannel 看到任何性能改进,并且您会遇到很多困难-如果你走那条路,就维护代码。

推理非常简单:无论您采取哪种方法,所涉及的步骤都是相同的:

  1. 生成字节。您没有说明您计划如何执行此操作,并且它可能会在方程式中引入额外级别的临时缓冲。但无论如何,Java 数据都必须转换为字节。
  2. 将字节累积到缓冲区中。您希望在写入数据之前对其进行缓冲,这样就不会进行大量的小写入。这是既定的。但缓冲区位于何处并不重要。
  3. 跨 JNI 屏障将字节从 Java 堆移动到 C 堆。写入文件是 native 操作,它不会直接从 Java 堆读取。因此,无论您在 Java 堆上缓冲然后移动缓冲的字节,还是在直接 ByteBuffer 中缓冲(是的,您需要一个直接缓冲区),您仍然移动字节。您将使用 ByteBuffer 进行更多 JNI 调用,但这是边际成本。
  4. 调用fwrite,这是一个内核调用,它将字节从 C 堆复制到内核维护的磁盘缓冲区中。
  5. 将内核缓冲区写入磁盘。这将超过所有其他步骤的总和,因为磁盘速度很慢

可能会增加或损失几微秒,具体取决于您实现这些步骤的具体方式,但您无法更改基本步骤。

FileChannel 确实为您提供了调用 force() 的选项,以确保步骤 #5 实际发生。这实际上可能会降低您的整体性能,因为底层的fsync调用在字节写入之前不会返回。如果您确实想要这样做,您始终可以从底层流中获取 channel 。

底线:我敢打赌,你实际上是受 IO 限制的,而且除了更好的硬件之外,没有任何解决办法。

关于java - 如何在 Java 中实现缓冲/批处理 FileChannel?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12587125/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com