tags:

views:

31

answers:

2

For example I have a file whose content is:

abcdefg

then i use the following code to read 'defg'.

ByteBuffer bb = ByteBuffer.allocate(4);
int read = channel.read(bb, 3);
assert(read == 4);

Because there's adequate data in the file so can I suppose so? Can I assume that the method returns a number less than limit of the given buffer only when there aren't enough bytes in the file?

+2  A: 

Can I assume that the method returns a number less than limit of the given buffer only when there aren't enough bytes in the file?

That's a good question. The javadoc does not specify what will happen, apart from saying that you will only get zero characters if you are at the end of file (or the equivalent).

In practice, you are likely to always get a full buffer when reading from a file, modulo the end of file scenario. And that makes sense from an OS implementation perspective, given the overheads of making a system call.

But, I can also imagine situations where returning a half empty buffer might make sense. For example, when reading from a locally-mounted remote file system over a slow network link, there is some advantage in returning a partially filled buffer so that the application can start processing the data. Some future OS may implement the read system call to do that in this scenario. If assume that you will always get a full buffer, you may get a surprise when your application is run on the (hypothetical) new platform.

Another issue is that there are some kinds of stream where you will definitely get partially filled buffers. Socket streams, pipes and console streams are obvious examples. If you code your application assuming file stream behavior, you could get a nasty surprise when someone runs it against another kind of stream ... and fails.

Stephen C
The Javadocs **do** specify that there is no guarantee that the number of bytes requested will be read.
Grodriguez
@Grodriguez ... that's what I said.
Stephen C
You said "The javadoc does not specify what will happen, apart from saying that you will only get zero characters if you are at the end of file (or the equivalent)." But the Javadoc does specify much more than that. It explicitly states that you cannot assume that the requested number of bytes will be read, and that the only guarantee is that in blocking mode, at least one byte will be read.
Grodriguez
@Grodriguez - *"you cannot assume that the requested number of bytes will be read"* is **NOT** a specification of what will happen. Rather, it is a statement that something is **unspecified**. When I said *"does not specify what will happen"*, I chose my words very carefully.
Stephen C
@Stephen: You are of course right. I guess I've seen so many people making wrong assumptions on this topic that I have become kind of trigger happy. My apologies.
Grodriguez
Thanks for the answer. And I do find sometimes on some Linux OS the method doesn't read bytes less than both specified and available. But when I wrote some code to test it, it never happen. Anyway i'll change my code to: while(bb.hasRemaining()) fc.read(bb)...
tactoth
+1  A: 

No, in general you cannot assume that the number of bytes read will be equal to the number of bytes requested, even if there are bytes left to be read in the file.

If you are reading from a local file, chances are that the number of bytes requested will actually be read, but this is by no means guaranteed (and won't likely be the case if you're reading a file over the network).

See the documentation for the ReadableByteChannel.read(ByteBuffer) method (which applies for FileChannel.read(ByteBuffer) as well). Assuming that the channel is in blocking mode, the only guarantee is that at least one byte will be read.

Grodriguez