2012-02-24 111 views
0

我正在从服务器下载文件,出于某种原因,我无法确定下载的文件大小是否与原始文件大小不匹配。这是我的代码。获取与android下载代码不匹配的文件大小

private class dl extends AsyncTask<String,Integer,Void> 
{ 
    int size; 
    @Override 
    protected Void doInBackground(String... arg0) { 
     // TODO Auto-generated method stub 
     try{ 
      URL myFileUrl = new URL("http://10.0.2.2:8080/testdlapps/chrome-beta.zip"); 
     HttpURLConnection conn = (HttpURLConnection) myFileUrl.openConnection(); 
     conn.setDoOutput(true); 
     conn.setRequestMethod("GET"); 
     conn.setDoInput(true); 
     conn.setConnectTimeout(5000); 
     conn.connect(); 

     InputStream is = conn.getInputStream(); 

     size = conn.getContentLength(); 
     Log.v("INFO---------------------", "size is " +size); 

     FileOutputStream fout1 = new FileOutputStream(Environment.getExternalStorageDirectory()+"/"+"xyz.zip"); 
     BufferedOutputStream bos = new BufferedOutputStream(fout1); 

     byte[] b = new byte[1024]; int i=0, count=0; 
     while((count = is.read(b)) != -1) 
     { 
      bos.write(b,0,count); 
      i+=count; 
      publishProgress(i); 
      Log.v("INFO----------------------------",""+count); 
     } 
     fout1.close(); 
     }catch(Exception e){ 
      Log.v("INFO--------------------------","Error!!"); 
      Log.v("INFO--------------------------",e.getMessage()); 
      e.printStackTrace(); 
     } 
     return null; 
    } 

    protected void onProgressUpdate(Integer... progress) { 
     tv.setText("downloaded " + progress[0] + "/" + size); //tv is a TextView 
    } 
} 

当我运行应用程序,下载完成后,计数和大小是相同的,但实际的文件大小即/mnt/sdcard/xyz.zip总是小于大小。任何想法出了什么问题?

回答

0

覆盖onPostExecute并检查是否实际上它完成,也许这里的代码下载与简历支持, 注意,因为如果你按下背面的下载可能仍运行:在循环

if (isCancelled()) 
    return false; 

是必要的,因为关闭()在插座上会挂在退出没有你noticeing它

这里是代码:

class DownloaderTask extends AsyncTask<String, Integer, Boolean> 
{ 
    private ProgressDialog mProgress; 
    private Context mContext; 
    private Long mFileSize; 
    private Long mDownloaded; 
    private String mDestFile; 

    public DownloaderTask(Context context, String path) 
    { 
     mContext = context; 
     mFileSize = 1L; 
     mDownloaded = 0L; 
     mDestFile = path; 
    } 

    @Override 
    protected void onPreExecute() 
    { 
     mProgress = new ProgressDialog(mContext); 
     mProgress.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); 
     mProgress.setMessage("Downloading..."); 
     mProgress.setCancelable(true); 
     mProgress.setCanceledOnTouchOutside(false); 
     mProgress.setOnCancelListener(new DialogInterface.OnCancelListener() 
     { 
      @Override 
      public void onCancel(DialogInterface dialog) 
      { 
       DownloaderTask.this.cancel(true); 
      } 
     }); 
     mProgress.show(); 

    } 

    @Override 
    protected void onProgressUpdate(Integer... percent) 
    { 
     mProgress.setProgress(percent[0]); 
    } 

    @Override 
    protected Boolean doInBackground(String... urls) 
    { 
     FileOutputStream fos = null; 
     BufferedInputStream in = null; 
     BufferedOutputStream out = null; 
     AndroidHttpClient mClient = AndroidHttpClient.newInstance("AndroidDownloader"); 

     try 
     { 

      HttpResponse response = null; 

      HttpHead head = new HttpHead(urls[0]); 
      response = mClient.execute(head); 
      if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) 
       return false; 

      Boolean resumable = response.getLastHeader("Accept-Ranges").getValue().equals("bytes"); 

      File file = new File(mDestFile); 
      mFileSize = (long) Integer.parseInt(response.getLastHeader("Content-Length").getValue()); 

      mDownloaded = file.length(); 

      if (!resumable || (mDownloaded >= mFileSize)) 
      { 
       Log.e(TAG, "Invalid size/Non resumable - removing file"); 
       file.delete(); 
       mDownloaded = 0L; 
      } 

      HttpGet get = new HttpGet(urls[0]); 

      if (mDownloaded > 0) 
      { 
       Log.i(TAG, "Resume download from " + mDownloaded); 
       get.setHeader("Range", "bytes=" + mDownloaded + "-"); 
      } 

      response = mClient.execute(get); 
      if ((response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) && (response.getStatusLine().getStatusCode() != HttpStatus.SC_PARTIAL_CONTENT)) 
       return false; 

      if (mDownloaded > 0) 
       publishProgress((int) ((mDownloaded/mFileSize) * 100)); 

      in = new BufferedInputStream(response.getEntity().getContent()); 
      fos = new FileOutputStream(file, true); 
      out = new BufferedOutputStream(fos); 

      byte[] buffer = new byte[8192]; 
      int n = 0; 
      while ((n = in.read(buffer, 0, buffer.length)) != -1) 
      { 
       if (isCancelled()) 
        return false; 

       out.write(buffer, 0, n); 
       mDownloaded += n; 
       publishProgress((int) ((mDownloaded/(float) mFileSize) * 100)); 
      } 

     } catch (Exception e) 
     { 
      e.printStackTrace(); 
      return false; 
     } finally 
     { 
      try 
      { 
       mClient.close(); 
       if (in != null) 
        in.close(); 
       if (out != null) 
        out.close(); 
       if (fos != null) 
        fos.close(); 
      } catch (IOException e) 
      { 
       e.printStackTrace(); 
      } 
     } 

     return true; 
    } 

    @Override 
    protected void onCancelled() 
    { 
     finish(); 
    } 

    @Override 
    protected void onPostExecute(Boolean result) 
    { 
     if (mProgress.isShowing()) 
      mProgress.dismiss(); 

     if (result) 
      // done 
     else 
      // error 
    } 

} 
+0

感谢您的代码,但它不会与Android操作系统比froyo更老的设备兼容(是的,当我发现它是要求的一部分时,我也感到震惊)。 AndroidHttpClient仅适用于2.2+ – 2012-02-24 06:55:49

+0

关于onPostExecute的建议应该仍然有效 – sherpya 2012-02-24 16:23:03

0

如果它是一个分块响应,那么标题中的内容长度最多只会是一个猜测。

+0

但是在这种情况下,内容长度标头始终是正确的。 – 2012-02-24 06:52:44