When I execute following class
import java.io.*;
import java.nio.*;
import java.nio.file.*;
import java.nio.channels.*;
public class FileChannelTest {
public static void main(final String... args) throws IOException {
final File file = File.createTempFile("temp", null);
file.deleteOnExit();
// write some
try(OutputStream output = new FileOutputStream(file)) {
output.write(new byte[128]);
output.flush();
}
System.out.println("length: " + file.length());
// read to end
try(FileChannel channel
= FileChannel.open(file.toPath(), StandardOpenOption.READ)) {
final ByteBuffer buffer = ByteBuffer.allocate(128);
for(int read; (read = channel.read(buffer)) != -1; ) {
System.out.println("read: " + read);
}
}
}
}
The reading loop never ends.
$ java -version
java version "1.8.0_65"
Java(TM) SE Runtime Environment (build 1.8.0_65-b17)
Java HotSpot(TM) 64-Bit Server VM (build 25.65-b01, mixed mode)
$ java FileChannelTest.java
$ java FileChannelTest
length: 128
read: 128
read: 0
read: 0
read: 0
...
...
...
FileChannel.read(ByteBuffer) says,
Reads a sequence of bytes from this channel into the given buffer. Bytes are read starting at this channel's current file position, and then the file position is updated with the number of bytes actually read. Otherwise this method behaves exactly as specified in the
ReadableByteChannel
interface.
What does Otherwise mean?
When you read into a ByteBuffer, it can only read as many bytes as is available in the buffer i.e. byteBuffer.remaining()
This means once the buffer is full, when you do a read it returns 0
.
I suggest you use either clear()
if you have consumed all the data read, or compact()
if you have consumed only a portion of the data read.
for(int read; (read = channel.read(buffer)) != -1; ) {
System.out.println("read: " + read);
buffer.clear(); // so we can read more data
}