如何在Java中实现缓冲/批处理文件通道?
这看起来并不简单,特别是对于读/写缓冲文件通道。是否有任何开源实现的地方,我可以根据我的实现如何在Java中实现缓冲/批处理文件通道?,java,io,real-time,nio,Java,Io,Real Time,Nio,这看起来并不简单,特别是对于读/写缓冲文件通道。是否有任何开源实现的地方,我可以根据我的实现 对于那些不理解的人来说,要清楚: FileChannel在操作系统级别执行缓冲,我想在Java级别执行缓冲。请阅读此处以了解: @Peter我想从一个快速的消息流将一个巨大的文件写入磁盘。缓冲和批处理是解决问题的方法。所以我想在Java中批处理,然后调用FileChannel.write。FileChannel只与ByteBuffers一起工作,所以它自然会被缓冲。如果您需要额外的缓冲来将数据从By
对于那些不理解的人来说,要清楚: FileChannel在操作系统级别执行缓冲,我想在Java级别执行缓冲。请阅读此处以了解:
@Peter我想从一个快速的消息流将一个巨大的文件写入磁盘。缓冲和批处理是解决问题的方法。所以我想在Java中批处理,然后调用FileChannel.write。FileChannel只与ByteBuffers一起工作,所以它自然会被缓冲。如果您需要额外的缓冲来将数据从ByteBuffer复制到ByteBuffer,但我不确定您为什么要这样做 FileChannel不在操作系统级别进行缓冲 FileChannel确实告诉操作系统要做什么。操作系统通常具有磁盘缓存,但FileChannel不知道是否存在这种情况 我想在Java级别进行缓冲
你很幸运,因为你别无选择这是唯一的选项。我将有两个线程,生产者线程生成ByteBuffers并将它们附加到队列尾部,消费者线程每次从队列头部移除一些ByteBuffers,并调用fileChannel.write(ByteBuffer[]).我建议使用
缓冲输出流
包装文件输出流
。我不相信通过使用ByteBuffer
和FileChannel
,您会看到任何性能改进,如果您这样做的话,将留下大量难以维护的代码
理由很简单:无论您采取何种方法,所涉及的步骤都是相同的:
ByteBuffer
中进行缓冲(是的,您需要直接缓冲),您仍然在移动字节。您将使用ByteBuffer
进行更多的JNI调用,但这是一个边际成本fwrite
,一种内核调用,它将字节从C堆复制到内核维护的磁盘缓冲区中FileChannel
确实提供了调用force()
的选项,以确保第5步实际发生。这实际上可能会降低整体性能,因为在写入字节之前,底层的fsync
调用不会返回。如果你真的想这样做,你总是可以从底层流中获取通道
一句话:我敢打赌,您实际上是IO绑定的,而且没有办法解决这一问题,因为您需要的是更好的硬件。不太清楚您想要的是什么,但是我现在能想到的最好的东西是
RandomAccessFile
类:@SimonAndréForsberg参考我在问题中的编辑…你是否证明了BufferedOutputStream
包装FileOutputStream
是不够的?当你这么做的时候,你有没有确认你实际上是CPU绑定的而不是IO绑定的?@parsifal没有,但我想使用FileChannel,因为我在处理ByteBuffers…什么是“快速消息流”?我想从一个快速消息流将一个大文件写入磁盘。缓冲和批处理是解决问题的方法。所以我想在Java中批处理,然后调用FileChannel.write。如果使用NIO,您没有任何其他选项,因此我不确定您在寻找什么。假设我必须批处理1000条消息。我不想调用FileChannel.write 1000次。我想用Java缓冲这个,然后他们只调用一次FileChannel.write。我想我想要一个批处理文件通道。这就是我要做的。如果您不需要定期写入磁盘,您可以使用64KB的单个字节缓冲区,当到达的消息溢出时,您可以将其写入磁盘并清除缓冲区。我有一个库Java编年史
,它只会在16MB到1GB的块中添加更多字节缓冲区映射的内存。它不使用强制或重新映射文件,只是不断添加到末尾。如果您有一个64位JVM,您可以通过这种方式写入超过8 TB的数据。FileOutputStream和FileChannel都是非阻塞的吗?我想是的。。。所以FileChannel的唯一优点是它可以直接使用ByteBuffer。它有我们不在乎的力。但正如人们之前提到的,FileChannel比FileOutputStream更快:我对所有这些帖子都持极大的保留态度。斯图·汤普森(Stu Thompson)就如何优化IO密集型应用程序给出了很多很好的建议,但他的基准测试结果可能(将)与您的应用程序关系不大。我想我忘记强调的一点是,我还需要在大文件的任意点上阅读。因此需要进行某种交换。@chrisapotek-我认为您最好描述我们应用程序的实际需求——所有这些需求——并征求实现建议。实际上,您只是给出了实现的一些细节,并询问如何添加您已经决定的另一个解决方案。@chrisapotek它们都不是非阻塞的。Java中唯一的非阻塞通道是那些exte