My story has start when I should implement some software where huge files should be read.
First what I have done was to look for an example of how to read a file by using the NIO package from Java SDK. In final I have found an example which was using the ByteBuffer class to read the data from file stream. I already do not remember, do I entirely copied that example or made some changes, but in final I get something like:
FileInputStream fis = new FileInputStream("myfile.txt");
FileChannel channel = fis.getChannel();
ByteBuffer buf = ByteBuffer.allocate(4);
int bytesRead = channel.read(buf);
while (bytesRead > 0) {
buf.rewind();
while(buf.remaining() > 0) {
System.out.print((char)buf.get());
}
buf.rewind();
bytesRead = channel.read(buf);
}
channel.close();
fis.close();
Ok, this is not real example from the project, but it similar. So it look like is OK, I thought the same, but what will print this code if the content of the myfile.txt will be 123456. That time I would suppose that it will be the 123456, but not! The real output is 12345634. Interesting, not? (at least for me it is :P). The answer why is happening is that on channel.read(buf), the buffer is not reset, but the values are replaced. So in above example the bytes which contains values 5 and 6 are replaced on 0th and 1st index of the buffer, and the 3rd and 4th index contains the previous values. Apparently the call of method buf.clear() will solve the problem, but look what Java Doc is saying: Clears this buffer. The position is set to zero, the limit is set to the capacity, and the mark is discarded.
Invoke this method before using a sequence of channel-read or put operations to fill this buffer. For example:
buf.clear(); // Prepare buffer for reading
in.read(buf); // Read data
This method does not actually erase the data in the buffer, but it is named as if it did because it will most often be used in situations in which that might as well be the case.
No comments:
Post a Comment