2012-02-24 108 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