有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

使用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);

问题是:哪种方法的性能和吞吐量最大


共 (2) 个答案

  1. # 1 楼答案

    为了最大限度地提高性能,我建议您尝试使用大约32KB的直接缓冲区。16 KB到64 KB的大小通常最适合您的系统

    对于文件通道,它应该能够每次读取/写入所有数据,因此我认为各种方法不会有任何区别。但是,在读取/写入套接字通道时,它可能会产生影响

  2. # 2 楼答案

    为什么要使用compact()它可能涉及重复复制大量数据

    如果您在写入之前读取的所有数据之前没有认真的理由执行另一次读取,那么您的第一种方法就是要走的路

    哦,顺便说一句:如果你只是想把数据从一个文件复制到另一个文件,那么看看^{},或者^{}。这是文件复制最有效的方法,因为这可能使用底层操作系统的非常高效的操作,例如DMA

    (编辑:transferTo()等。当然,不需要任何ByteBuffer,这里混合了两种想法:)