2011-11-20 81 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