使用ByteBuffer性能比较在通道上执行java I/O操作
我想使用ByteBuffer
在通道上执行I/O操作。最后我提出了三个解决方案:
FileChannel inChannel = new FileInputStream("input.txt").getChannel();
FileChannel outChannel = new FileOutputStream("output.txt").getChannel();
ByteBuffer buf = ByteBuffer.allocate(1024 * 1024);
方法1:使用hasRemaining()
while (inChannel.read(buf) != -1) {
buf.flip();
while (buf.hasRemaining()) {
outChannel.write(buf);
}
buf.clear();
}
方法2:使用compact()
while (inChannel.read(buf) != -1 || buf.position() > 0) {
buf.flip();
outChannel.write(buf);
buf.compact();
}
方法3:混合模型
while (inChannel.read(buf) != -1) {
buf.flip();
outChannel.write(buf);
buf.compact();
}
// final flush of pending output
while (buf.hasRemaining())
outChannel.write(buf);
问题是:哪种方法的性能和吞吐量最大
# 1 楼答案
为了最大限度地提高性能,我建议您尝试使用大约32KB的直接缓冲区。16 KB到64 KB的大小通常最适合您的系统
对于文件通道,它应该能够每次读取/写入所有数据,因此我认为各种方法不会有任何区别。但是,在读取/写入套接字通道时,它可能会产生影响
# 2 楼答案
为什么要使用
compact()
它可能涉及重复复制大量数据如果您在写入之前读取的所有数据之前没有认真的理由执行另一次读取,那么您的第一种方法就是要走的路
哦,顺便说一句:如果你只是想把数据从一个文件复制到另一个文件,那么看看^{} ,或者^{} 。这是文件复制最有效的方法,因为这可能使用底层操作系统的非常高效的操作,例如DMA
(编辑:transferTo()等。当然,不需要任何ByteBuffer,这里混合了两种想法:)