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?
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(), ortransferFrom(). 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 :))