2011-09-13 40 views
5

我正在構建一個Android應用程序,我需要從33 MB大的url下載文件。Android:「意外的流結束」異常下載大文件

這裏下載任務:

try { 
      int MAX_BUFFER_SIZE = 4096; 
      URL mUrl = new URL(params[0]); 
      HttpURLConnection connection = (HttpURLConnection) mUrl.openConnection(); 
      connection.setRequestMethod("GET"); 
      long length = connection.getContentLength(), downloaded = 0; 
      int read; 
      byte [] buffer = new byte[(((int)length) > MAX_BUFFER_SIZE) ? MAX_BUFFER_SIZE : (int)length]; 
      String filename = getFilename(mUrl); 
      File file = new File (SDCARD_ROOT); 
      if (!file.exists() || !file.isDirectory()){ 
       file.mkdir(); 
      } 
      this.filename = filename; 
      file = new File (SDCARD_ROOT + this.filename); 
      FileOutputStream fos = new FileOutputStream (file); 
      //Start downloading 
      InputStream stream = connection.getInputStream(); 

      while ((read=stream.read(buffer)) > -1){ 
       fos.write(buffer, 0, read); 
       downloaded += read; 
       publishProgress((int) ((float) downloaded/length * 100)); 
      } 
      fos.close(); 
      return 1; 
     } catch (Exception e){ 
      Log.e("REV-PARTS", "Revolver parts error in DownloadTask: " + e.getMessage()); 
      return 2; 
     } 

它的工作原理正確的小文件(1-15 MB),但它會返回一個異常「流意外結束」大文件。 在此先感謝。

+0

哪個調用引發異常? 'stream.read()'? –

+1

是的,stream.read – Gnufabio

+0

@Gnufabio你能解決這個問題嗎? –

回答

-2

,而你捕獲異常,我想盡了辦法downContinue(),我可以告訴我的代碼:

private void downloadApk() { 
    thread1 = new Thread() { 
     public void run() { 
      File oFile = null; 
      try { 
       URL url = new URL(PQGLApplication.resrootURL + "apk/PQGLMap.apk"); 
       HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(); 
       ReadableByteChannel channel = 
         Channels.newChannel(urlConnection.getInputStream()); 
       oFile = 
         new File(Environment.getExternalStorageDirectory().getAbsolutePath() 
           + "/" + "hy_ht_new/" + "test2" + ".apk"); 
       oFile.setWritable(true); 
       oFile.setReadable(true); 
       if (oFile.exists()) { 
        oFile.delete(); 
       } 
       FileOutputStream fos = new FileOutputStream(oFile); 
       fileSize = urlConnection.getContentLength(); 
       ByteBuffer buffer = ByteBuffer.allocate(1024); 
       int noOfBytes = 0; 
       byte[] data = null; 
       sendApkMessage(0, 0); 
       while ((noOfBytes = channel.read(buffer)) > 0) { 
        data = new byte[noOfBytes]; 
        System.arraycopy(buffer.array(), 0, data, 0, noOfBytes); 
        buffer.clear(); 
        fos.write(data, 0, noOfBytes); 
        downLoadFileSize += noOfBytes; 
        sendApkMessage(1, downLoadFileSize); 
       } 
       fos.flush(); 
       fos.close(); 
       channel.close(); 
       sendApkMessage(2, oFile.getAbsolutePath()); 
      } catch (Exception e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
       downContinue(); 
      } 
     }; 
    }; 
    thread1.start(); 
} 

private void downContinue() { 
    continueTime++; 
    try { 
     if (continueTime == 3) { 
      continueTime = 0; 
      sendApkMessage(4, 0); 
      Log.e("what is the fucking continuetime", "continueTime" + continueTime); 
     } else { 
      URL url = new URL(PQGLApplication.resrootURL + "apk/PQGLMap.apk"); 
      HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(); 
      File oFile = 
        new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/" 
          + "hy_ht_new/" + "test2" + ".apk"); 
      RandomAccessFile oSavedFile = new RandomAccessFile(oFile, "rw"); 
      FileOutputStream fos = new FileOutputStream(oFile); 
      ReadableByteChannel channel = Channels.newChannel(urlConnection.getInputStream()); 
      // oSavedFile.seek(nPos); 
      ByteBuffer buffer = ByteBuffer.allocate(1024); 
      byte[] data = null; 
      int temp = 0; 
      sendApkMessage(3, oFile.getAbsolutePath()); 
      while ((temp = channel.read(buffer)) > 0) { 
       data = new byte[temp]; 
       System.arraycopy(buffer.array(), 0, data, 0, temp); 
       buffer.clear(); 
       fos.write(data, 0, temp); 
      } 
      fos.flush(); 
      fos.close(); 
      oSavedFile.close(); 
      sendApkMessage(2, oFile.getAbsolutePath()); 
      continueTime = 0; 
     } 
    } catch (Exception e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
     Log.e("what is the fucking exception", e.toString() + continueTime); 
     downContinue(); 
    } 

} 

這downContinue方法用於至少解決這個problem.At,文件下載成功! 我來自China.My英語不太好。

+0

你可以解釋一下sendApkMessage()方法,它究竟做了什麼? – skygeek

+0

您不需要設置輸出文件的可讀性或可寫性,或者在存在的情況下將其預先刪除。 '新的FileOutputStream()'已經有了所有這些效果。你也不需要'System.arraycopy()'。方法依賴於未指定的外部代碼。 – EJP

-1

對於大型文件,您需要使用以下代碼手動設置連接超時。 我已經設置了超時3分鐘

connection.setConnectTimeout(180000); 
    connection.setReadTimeout(180000); 
+0

這將如何解決「意外的流結束」問題? – EJP

+0

它會因爲此錯誤在下載期間由於超時而發生, –

0

我對此有一個答案。 你應該爲你的連接添加一個頭。

connection.setRequestProperty("Accept-Encoding", "identity"); 

這將有助於you.say我,如果它幫助...

0

設置塊大小似乎爲我工作。

connection.setChunkedStreamingMode(1048576);