In the nio.channels there is a FileChannel class that you can use to get a MappedByteBuffer, which has a method called array that will return a byte array. I believe the nio stuff is very effecient (someone with a lot of experience using it may want to speak up here).
The NIO stuff can be much more efficient than traditional I/O, but not always; sometimes it may even be slower. A MappedByteBuffer is most applicable for a large file you need to access multiple times. You may also find a regular ByteBuffer to be useful, using FileChannel's read(ByteBuffer) method. However you can also get better performance than you do currently using tradional I/O. Specifically, you can read directly into a byte array, rather than reading one byte at a time and transferring to an intermediate object like BAOS. Try something like:
The loop is necessary because read(byte, int, int) isn't guaranteed to read all requested bytes at once. But it generally reads a lot of bytes at once, which is more efficient than a bunch of separate reads. And in this case you don't need the BufferedInputStream - the destination array is your buffer. I don't believe you can make this operation any more efficient using tradional I/O.
Observe that variable count is never used. What's the meaning of offset + length ? What's the meaning of that while loop? It executes only once, and only once. The line in.read(array, offset, (length - offset)); never changes length or offset. When while loop is first time executed, offset is 0, and length is the length of the file, and, becaouse zero is, should be in some case, less then a length of the file, the loop starts to be executed. Before the end of the loop offset is setted to have a value of the length of the file, and becaouse of that when while loop checks again its condition, it doesn't enter into a second loop.
But what should happen is, that, it enters into another loop if the file is not read until the end, what is not done here, but that what's described.
The method read returns integer, quote from javadoc:
Reads up to len bytes of data from the input stream into an array of bytes. An attempt is made to read as many as len bytes, but a smaller number may be read. The number of bytes actually read is returned as an integer.
So... It should loop until the file is read, and that can be seen in the return value of the read method. Everytime that something is read from the file, the number of not read bytes is smaller and smaller. The 'offset' variable should be incremented with the 'count' varible, not 'length' variable.
, or maybe like this?
But I have a question. (?)
file.length(); returns long. Here it's casted to an integer. What if the return value is bigger than a maximum integer?
Joined: Jan 30, 2000
Yes, obviously "offset += length" should have been "offset += count". Thanks for the catch.
Vanja Sanjin wrote:file.length(); returns long. Here it's casted to an integer. What if the return value is bigger than a maximum integer?
Presumably Raymond inserted the cast to int because "new byte[length]" doesn't work for a long length. Ultimately if the file length is longer than Integer.MAX_VALUE, there's no way to read everything into a single byte array anyway; we should probably just error out instead.
Joined: May 04, 2012
Thank you for the thought. I think that max integer is for file of 2 GB (byte +/-).