views:

174

answers:

1

I am trying to download a zip file using HttpCLient 4 and it is going at around .5 (kilobytes/kilobits)? per minute. The file is less than a MB large, and the download will probably take an hour! Am I doing something wrong? How else should I do this? Here is my current implementation:

@Override
            protected Uri doInBackground(String... params) {
                publishProgress("Downloading...");  
                try {
                        HttpPost searchPOST = new HttpPost("http://www.somesite.com/" + searchResult.getURLSuffix());
                        List<NameValuePair> formparams = new ArrayList<NameValuePair>();
                        //added parameters here...
                        UrlEncodedFormEntity paramsEntity = new UrlEncodedFormEntity(formparams, HTTP.UTF_8);
                        searchPOST.setEntity(paramsEntity);


                HttpResponse manualResponse = client.execute(searchPOST);

                Header fileNameHeader = manualResponse.getFirstHeader("Content-Disposition");
                Pattern p = Pattern.compile("filename=\"(.+?)\"");
                Matcher m = p.matcher(fileNameHeader.getValue());

                if (m.find()) {
                    String fileName = m.group(1);
                    InputStream zipStream = manualResponse.getEntity().getContent();
                    File cacheDir = context.getCacheDir();
                    String tempFileForZip = cacheDir.getAbsolutePath() + "/" + fileName;
                    FileOutputStream fos = new FileOutputStream(tempFileForZip);
                    int bytesDownloaded = 0;
                    try {
                        int c;
                        while ((c = zipStream.read()) != -1) {
                            fos.write(c);
                            bytesDownloaded++;
                            kilobytesDownloaded=(bytesDownloaded / 1000);
                            publishProgress((String[])null);
                        }
                    } finally {
                        if (zipStream != null) {
                            zipStream.close();
                        }
                        if (fos != null) {
                            fos.close();
                        }
                    }

                    fos.close();


                String zipFilePath = tempFileForZip;

                //Change to indeterminate
                kilobytesDownloaded = fileSize;
                publishProgress("Extracting...");

                //TODO: Preferences for save directory
                saveDirectory = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + "Downloads/");
                ZipTools.unzipArchive(new File(zipFilePath), saveDirectory);

                }

                    } catch (IllegalStateException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    } finally {

                    }

                return Uri.fromFile(saveDirectory);
         }
+2  A: 

Step #1: Do not call publishProgress() for every byte.

Step #2: Read more than a byte at a time. Better yet, don't use the InputStream directly -- use HttpEntity#writeTo() to have HttpClient write your data to the output file.

CommonsWare
@CommonsWare good step #2, I had never noticed the writeTo method before. I recently found the reason our JAI-based PNG resizing was so slow on some images - Java's PNGDecoder inflates and reads zTXt chunks a byte at a time, making it take about five minutes to resize a tiny image. After recompiling with a simple fix to use a byte buffer, it's hundreds of times faster.
Nick
How do I update progress using this method?
Aymon Fournier
@Aymon Fournier: Well, I'd start with Step #1, and download in larger chunks (e.g., 10K). I do not know how you would update progress using Step #2.
CommonsWare
I am trying to update a progress bar, so if I can't update the progress bar... I need another solution
Aymon Fournier
@Aymon Fournier: Well, I'd start with Step #1, and download in larger chunks (e.g., 10K).
CommonsWare
II actually copied the code from the writeTo method, and put publishProgress after every 3 [2048]byte cycles! works great.
Aymon Fournier