I`m trying to read an image from an URL (with the java package java.net.URL) to a byte[]. "Everything" works fine, except that the content isnt being enterely read from the stream (the image is corrupt, it doesnt contain all the image data)... The byte array is being persisted in a database (BLOB). I really dont know what the correct approach is, maybe you can give me a tip :)
This is my first approach (code formatted, removed unnecessary informations...):
URL u = new URL("http://localhost:8080/images/anImage.jpg");
int contentLength = u.openConnection().getContentLength();
Inputstream openStream = u.openStream();
byte[] binaryData = new byte[contentLength];
openStream.read(binaryData);
openStream.close();
My second approach was this one (as you'll see the contentlength is being fetched another way):
URL u = new URL(content);
openStream = u.openStream();
int contentLength = openStream.available();
byte[] binaryData = new byte[contentLength];
openStream.read(binaryData);
openStream.close();
Both of the code result in a corrupted image... I already read this post from stackoverflow
I am very surprised that nobody here has mentioned the problem of connection and read timeout. It could happen (especially on Android and/or with some crappy network connectivity) that the request will hang and wait forever.
The following code (which also uses Apache IO Commons) takes this into account, and waits max. 5 seconds until it fails:
The content length is just a HTTP header. You cannot trust it. Just read everything you can from the stream.
Available is definitely wrong. It's just the number of bytes that can be read without blocking.
Another issue is your resource handling. Closing the stream has to happen in any case. try/catch/finally will do that.
There's no guarantee that the content length you're provided is actually correct. Try something akin to the following:
You'll then have the image data in
baos
, from which you can get a byte array by callingbaos.toByteArray()
.This code is untested (I just wrote it in the answer box), but it's a reasonably close approximation to what I think you're after.
Just extending Barnards's answer with commons-io. Separate answer because I can not format code in comments.
http://commons.apache.org/io/api-1.4/org/apache/commons/io/IOUtils.html#toByteArray(java.io.InputStream)
Here's a clean solution:
Note however, that stream is not closed in the above example.
if you want a (76-character) chunk (using commons codec)...