2011-11-20 80 views
10

可能重複:
Android:「Unexpected end of stream」 exception downloading large files下載意外的流錯誤結束?

我downloding大約一個文件。 5MB使用HttpURLConnection類,但downlod在半路上我在這行我的代碼得到錯誤的「流意外結束」:

     while ((count = input.read(data)) > 0) { 

這裏是LOG:

11-20 16:05:55.749: ERROR/PRINTSTACK(3425): STACK:unexpected end of stream 
11-20 16:05:55.749: WARN/System.err(3425): java.io.IOException: unexpected end of stream 
11-20 16:05:55.749: WARN/System.err(3425):  at org.apache.harmony.luni.internal.net.www.protocol.http.FixedLengthInputStream.read(FixedLengthInputStream.java:47) 
11-20 16:05:55.749: WARN/System.err(3425):  at java.io.BufferedInputStream.read(BufferedInputStream.java:319) 
11-20 16:05:55.749: WARN/System.err(3425):  at java.io.FilterInputStream.read(FilterInputStream.java:133) 
11-20 16:05:55.759: WARN/System.err(3425):  at com.conjure.skiproj.DownloadService$Job.process(DownloadService.java:265) 
11-20 16:05:55.759: WARN/System.err(3425):  at com.conjure.skiproj.DownloadService$1.run(DownloadService.java:193) 
11-20 16:05:55.759: WARN/System.err(3425):  at java.lang.Thread.run(Thread.java:1019) 

幫助! 1

編輯:在代碼的詳細信息建立的InputStream:

HttpURLConnection conexion = (HttpURLConnection)url.openConnection(); 
         conexion.setRequestMethod("GET"); 
         conexion.setReadTimeout(20000); 
         conexion.connect(); 
         File file = new File(root.getAbsolutePath()+"/", fileName); 

          int lenghtOfFile = conexion.getContentLength(); 

          InputStream input = new BufferedInputStream(url.openStream()); 

          OutputStream output = new FileOutputStream(file); 

          byte data[] = new byte[8192]; 
........................... 

編輯2:上得了在下一行下載的25%,新的錯誤IndexOutOfBoundsException異常:下面

output.write(data, 0, count); 

LOG:

11-20 17:47:02.311: ERROR/totaltotal(303): 24 
11-20 17:47:02.311: INFO/System.out(303): countcountcount:4332 
11-20 17:47:02.330: ERROR/totaltotal(303): 24 
11-20 17:47:02.330: INFO/System.out(303): countcountcount:2904 
11-20 17:47:02.330: ERROR/totaltotal(303): 25 
11-20 17:47:02.330: INFO/System.out(303): countcountcount:1452 
11-20 17:47:02.330: ERROR/totaltotal(303): 25 
11-20 17:47:02.650: INFO/System.out(303): countcountcount:4356 
11-20 17:47:02.650: ERROR/totaltotal(303): 25 
11-20 17:47:02.650: INFO/System.out(303): countcountcount:-1 
11-20 17:47:02.660: ERROR/totaltotal(303): 25 
11-20 17:47:02.892: DEBUG/dalvikvm(303): GC_FOR_MALLOC freed 10770 objects/490896 bytes in 143ms 
11-20 17:47:03.060: ERROR/PRINTSTACK(303): STACK:Arguments out of bounds 
11-20 17:47:03.060: WARN/System.err(303): java.lang.IndexOutOfBoundsException: Arguments out of bounds 
11-20 17:47:03.070: WARN/System.err(303):  at java.io.FileOutputStream.write(FileOutputStream.java:288) 
11-20 17:47:03.080: WARN/System.err(303):  at com.conjure.skiproj.DownloadService$Job.process(DownloadService.java:275) 
11-20 17:47:03.080: WARN/System.err(303):  at com.conjure.skiproj.DownloadService$1.run(DownloadService.java:191) 
11-20 17:47:03.080: WARN/System.err(303):  at java.lang.Thread.run(Thread.java:1096) 

編輯3: 我追查錯誤回FixedLengthInputStream然後進一步回到AbstractHttpInputStream類,其中有這種方法:

/** 
      * Calls abort on the cache entry and disconnects the socket. This 
      * should be invoked when the connection is closed unexpectedly to 
      * invalidate the cache entry and to prevent the HTTP connection from 
      * being reused. HTTP messages are sent in serial so whenever a message 
      * cannot be read to completion, subsequent messages cannot be read 
      * either and the connection must be discarded. 
      * 
      * <p>An earlier implementation skipped the remaining bytes, but this 
      * requires that the entire transfer be completed. If the intention was 
      * to cancel the transfer, closing the connection is the only solution. 
      */ 
      protected final void unexpectedEndOfInput() { 
       if (cacheRequest != null) { 
        cacheRequest.abort(); 
       } 
       httpURLConnection.releaseSocket(false); 
      } 

因此,看起來在Http消息錯誤的情況下,整個下載流被取消。

+0

我懷疑它會幫助,但嘗試使用'InputStream input = conexion.getInputStream();'而不是使用'url.openStream()'創建一個'BufferedInputStream'。 – Squonk

+0

剛剛嘗試過,它不起作用! – bytebiscuit

+1

任何人對於如何解決這個問題或任何提示或方向都有任何想法! – bytebiscuit

回答

0

據我瞭解,在網絡問題的情況下,計數爲0是允許的。嘗試...

while ((count = input.read(data)) != -1) { 
    if (count != 0) { 
     ... 
    } 
} 
+0

nope仍然有錯誤:S – bytebiscuit

+0

我不認爲這裏應該允許0。從[InputStream文檔](http://download.oracle.com/javase/6/docs/api/):如果b的長度爲零,則不讀取字節並返回0;否則,嘗試讀取至少一個字節。如果由於流位於文件末尾而沒有可用字節,則返回值-1;否則,至少讀取一個字節並存儲到b._ –

+0

@Ted:好的,我同意你的說明,但是當我的應用程序正在下載某些文件時,我遇到了一個測試版測試人員遇到問題。一位Java程序員本人,他建議我按照上面的答案構建自己的代碼。他建議,當與網絡流關聯時,可能會發生0字節的返回。它修復了他的下載失敗。此外,在這種情況下,這是一個有爭議的問題,因爲它沒有解決OP的問題。 – Squonk

8

即異常由FixedLengthInputStream拋出時所期望的字節數(通常在響應的內容長度報頭中設置)比在響應中的實際數據大。檢查內容長度標題是否正確。 (如果您爲內容長度提供自己的值,請確保它是正確的。)

這將有助於查看設置輸入流的代碼。

+0

剛編輯我的問題。提供了更多信息。 – bytebiscuit

+0

它仍然看起來像內容長度標題是錯誤的。此外,如果您只是在讀取數據並將其轉儲到文件中,則無需將輸入流包裝在BufferedInputStream中。你已經在使用你自己的緩衝區,並且像這樣的雙緩衝只會增加開銷。它不應該影響任何東西,但嘗試擺脫那個包裝。 –

+0

內容長度沒問題,我得到的文件大小正確5171472(〜5.2MB) – bytebiscuit