• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Reading file into byte array

 
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi,
How do I read file into byte array?
Is there any method other than reading each character and write into byte array.
Right now I am using the following code ..
Is there any efficient way to read file into byte array ?
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(args[0]));
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int c;
while ((c = bis.read()) > -1) {
baos.write(c);
}
bis.close();
byte[] buf = baos.toByteArray();

Thanks,
Tom.
 
Chicken Farmer ()
Posts: 1932
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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).
 
Wanderer
Posts: 18671
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.
 
Greenhorn
Posts: 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
This works nicely fixed above post.
 
Greenhorn
Posts: 7
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
There is still error in this code.

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?


 
Jim Yingst
Wanderer
Posts: 18671
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.
 
Vanja Sanjin
Greenhorn
Posts: 7
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thank you for the thought. I think that max integer is for file of 2 GB (byte +/-).

2^31 = 2147483648 bytes = 2097152 kb = 2048 mb
 
Don't get me started about those stupid light bulbs.
reply
    Bookmark Topic Watch Topic
  • New Topic