3

I am loading a image from the web to the local android phone. The code that I have for writing to a file is as follows

        BufferedInputStream bisMBImage=null;
        InputStream isImage = null;
        URL urlImage = null;
        URLConnection urlImageCon = null;
        try 
        {
                urlImage = new URL(imageURL); //you can write here any link
                urlImageCon = urlImage.openConnection();
                isImage = urlImageCon.getInputStream();
                bisMBImage = new BufferedInputStream(isImage);

                int dotPos = imageURL.lastIndexOf(".");
                if (dotPos > 0 )
                {
                    imageExt = imageURL.substring(dotPos,imageURL.length());    
                }

                imageFileName = PATH + "t1" + imageExt;
                File file = new File(imageFileName);
                if (file.exists())
                {
                    file.delete();
                    Log.d("FD",imageFileName + " deleted");
                }
                 ByteArrayBuffer baf = new ByteArrayBuffer(255);
                 Log.d("IMAGEWRITE", "Start to write image to Disk");
                 int current = 0;
                 try 
                 {
                    while ((current = bisMBImage.read()) != -1) 
                    {
                             baf.append((byte) current);
                    }

                    FileOutputStream fos = new FileOutputStream(file);
                    fos.write(baf.toByteArray());
                    fos.close();    
                    Log.d("IMAGEWRITE", "Image write to Disk done");
                } 
                catch (IOException e) 
                {
                    e.printStackTrace();
                }                       

                isImage.close();
        } 
        catch (IOException e) 
        {
                Log.d("DownloadImage", "Error: " + e);
        }
        finally
        {
            isImage = null;         
            urlImageCon = null;
            urlImage = null;
        }

For some reason the whole writing to a file takes 1 minute. Is there a way I can optimize this ?

vikramjb
  • 1,365
  • 3
  • 25
  • 50
  • Similar to what Otra asks - how big is the image? Also I see you've put the 'android-emulator' tag on this question - the emulator can be slow for certain things although I don't use it so I'm not sure if that includes file download / writing. Have you tried this on a real device to see how long it takes? – Squonk Sep 14 '11 at 17:41
  • Is this running on the main UI thread or in a separate thread? – WindsurferOak Sep 14 '11 at 17:47
  • @Otra, the image is around 50-70 KB. – vikramjb Sep 14 '11 at 18:23
  • @mistersquonk, it takes a little less but slow even in device. – vikramjb Sep 14 '11 at 18:25
  • @WindsurferOak, its running on a separate thread. – vikramjb Sep 14 '11 at 18:25

2 Answers2

2

Your buffer is very small: 255 bytes. You could make it 1024 times bigger (255 kilobytes). This is an acceptable size and this would certainly speed up the thing.

Also, this is very slow as it reads the bytes one by one:

while ((current = bisMBImage.read()) != -1)  {
    baf.append((byte) current);
}

You should try using the array version of read() instead: read(byte[] buffer, int offset, int byteCount) with an array as large as what I have described above.

Shlublu
  • 10,917
  • 4
  • 51
  • 70
2

You should use the Android HttpClient for file fetching over the java URL Connection. Also your Buffer is very small. Try this snipped:

FileOutputStream f = new FileOutputStream(new File(root,"yourfile.dat"));

DefaultHttpClient httpClient = new DefaultHttpClient();
HttpGet request = new HttpGet(urlString);
HttpResponse response = httpClient.execute(request);
InputStream is = response.getEntity().getContent();

byte[] buffer = new byte[1024];
int len1 = 0;
while ( (len1 = is.read(buffer)) > 0 ) {
        f.write(buffer,0, len1);
}
f.close();
Michele
  • 6,126
  • 2
  • 41
  • 45
  • 2
    I would like to add that if you're doing HttpGet/HttpClient, you might as well get the headers in which case you know exactly how many bytes you are getting by reading the `Content-Length` and you could make your `byte[]` exactly that size. – Otra Sep 14 '11 at 18:10
  • @Otra, on the other way around, in case the file is very large, you could get an OutOfMemoryError – dwbrito Oct 21 '14 at 23:20