Frage

I want to perform I/O operation on channels using ByteBuffer. Finally I came up with three solutions:

FileChannel inChannel = new FileInputStream("input.txt").getChannel();
FileChannel outChannel = new FileOutputStream("output.txt").getChannel();
ByteBuffer buf = ByteBuffer.allocate(1024 * 1024);

Method 1: using hasRemaining()

while (inChannel.read(buf) != -1) {
    buf.flip();    
    while (buf.hasRemaining()) {
        outChannel.write(buf);
    }    
    buf.clear();
}

Method 2: using compact()

while (inChannel.read(buf) != -1 || buf.position() > 0) {
    buf.flip();
    outChannel.write(buf);
    buf.compact();
}

Method 3: hybrid model

while (inChannel.read(buf) != -1) {
    buf.flip();
    outChannel.write(buf);
    buf.compact();
}
// final flush of pending output
while (buf.hasRemaining())
    outChannel.write(buf);

The question is: Which method has the most performance and throughput?

War es hilfreich?

Lösung

Why would you want to use compact() at all? - It may involve copying of a lot of data repeatedly.

Your 1st method is the way to go if you don't have serious reason to perform another read before all of the previously read data is written.

Oh, and by the way: If you're only out for copying data from one file to another have a look at transferTo(), or transferFrom(). This is the most performant way for file copy as this may use very efficient operations of the underlying OS, like DMA, for instance.

(Edit: transferTo() etc. do of course not need any ByteBuffer, mixed two thoughts there :))

Andere Tipps

To maximise performance I suggest you try a direct buffer which is about 32 KB. This sizes of 16 KB to 64 KB often work best depending on your system.

For file channels it should be able to read/write all the data every time, so I don't think the various methods will make any difference. It can make a difference when reading/writing to Socket Channels however.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top