0

I am facing a problem downloading PNG images from my server to my Android app. The problem is specific to PNG images (JPG works fine), and the issue is that the downloaded files are corrupt images. I will explain in more details, below.

Scenario :

I need to download JPG and PNG images from my server, and display them to the user of the Android app.

Issue :

The JPG images get downloaded without an issue. But the downloaded PNG files are corrupt. I have double checked the source of the images at my server, and they are proper. Its only the downloaded PNG files, that are corrupt. So, the problem probably lies in the way I am downloading them in Android.

Code Sample :

URL imageURL;
File imageFile = null;
InputStream is = null;
FileOutputStream fos = null;
byte[] b = new byte[1024];

try {
    // get the input stream and pass to file output stream
    imageURL = new URL(image.getServerPath());
    imageFile = new File(context.getExternalFilesDir(null), image.getLocalPath());
    fos = new FileOutputStream(imageFile);

    // get the input stream and pass to file output stream
    is = imageURL.openConnection().getInputStream();
    // also tried but gave same results :
    // is = imageURL.openStream();

    while(is.read(b) != -1)
        fos.write(b);

} catch (FileNotFoundException e) {
} catch (MalformedURLException e) {
} catch (IOException e) {
} finally {
    // close the streams
    try {
        if(fos != null)
            fos.close();
        if(is != null)
            is.close();
    } catch(IOException e){
    }
}

Any pointers on how I can work on this, will be very appreciated.

Note :

Since this is happening in a service, there are no problems of doing this inside an AsyncTask.

Rohitesh
  • 967
  • 2
  • 14
  • 29

1 Answers1

2

The problem is here

 while(is.read(b) != -1)
        fos.write(b);

This is wrong, because in each iteration it will write the full buffer (1024 bytes) to the file. But the previous read could have read less bytes than than (almost surely on the last loop, unless the image lenght happens to be exactly a multiple of 1024). You should check how many bytes were read each time, and write that amount of bytes.

 int bytesRead;
 while( (bytesRead = is.read(b)) != -1)
        fos.write(b,0,bytesRead );

Your error makes you write always files with sizes that are multiple of 1024 - which of course is not the case in general. Now, what happens when a image is saved with extra trailing bytes depends on the format and on the image reader. In some cases, it might work. Still, it's wrong.

BTW: never swallow exceptions - even if that's not the problem today, it might be tomorrow and you might spend hours finding the problem.

leonbloy
  • 73,180
  • 20
  • 142
  • 190
  • Thank you! This solved the issue! Apologies for the delay in coming back and checking things here, as I was caught up with something! – Rohitesh Apr 23 '15 at 07:04