2011-11-20 9 views
10

Duplicar posible:
Android:“Unexpected end of stream” exception downloading large fileserror inesperado al finalizar la secuencia al descargar?

estoy downloding un archivo de aprox. 5 MB utilizando HttpURLConnection pero a mitad de camino durante el downlod me sale un "inesperado final de la corriente" error en esta línea de mi código:

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

Aquí es el REGISTRO:

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) 

Ayuda !! 1

EDIT: más información sobre el código de la configuración del flujo de entrada:

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]; 
........................... 

EDIT 2: Tienes un nuevo IndexOutOfBoundsException error en el 25% de descarga en la línea siguiente: por debajo de

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) 

EDITAR 3: I trazó el error de nuevo a FixedLengthInputStream clase y luego más atrás a la clase AbstractHttpInputStream en donde existe este método:

/** 
      * 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); 
      } 

Parece que en el caso de un error de mensaje Http, toda la secuencia de descarga se cancela.

+0

Dudo que sea útil pero intente utilizar 'InputStream input = conexion.getInputStream();' en lugar de usar 'url.openStream()' para crear un 'BufferedInputStream'. – Squonk

+0

acaba de probar esto, ¡no funciona! – bytebiscuit

+1

¡ALGUIEN TIENE CUALQUIER IDEA SOBRE CÓMO DIRIGIRSE A RESOLVER ESTO, O CUALQUIER CONSEJO O DIRECCIÓN !!! – bytebiscuit

Respuesta

0

Por lo que tengo entendido, se permite un conteo de 0 en caso de problemas de red. Trate ...

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

todavía tiene el error: S – bytebiscuit

+0

No creo que 0 deba permitirse aquí. De [docs for InputStream] (http://download.oracle.com/javase/6/docs/api/): _Si la longitud de b es cero, no se leen bytes y se devuelve 0; de lo contrario, hay un intento de leer al menos un byte. Si no hay bytes disponibles porque la secuencia se encuentra al final del archivo, se devuelve el valor -1; de lo contrario, al menos un byte se lee y almacena en b._ –

+0

@Ted: OK, estoy de acuerdo con lo que dice la documentación, pero tuve un problema con uno de mis beta-testers al obtener fallas cuando mi aplicación descargaba algunos archivos . Como programador de Java, sugirió que estructure mi código como en mi respuesta anterior. Sugirió que podría producirse un retorno de 0 bytes cuando se asocia con un flujo de red. Solucionó sus fallas de descarga.Además, en este caso es un punto discutible ya que no solucionó el problema del OP. – Squonk

8

Esa excepción es lanzada por FixedLengthInputStream cuando el número esperado de bytes (normalmente situada en la cabecera Content-Length de la respuesta) es más grande que los datos reales de la respuesta. Verifique que el encabezado de longitud del contenido sea correcto. (Si está suministrando su propio valor para la longitud del contenido, asegúrese de que sea correcto.)

Ayudaría a ver su código que configura el flujo de entrada.

+0

Acabo de editar mi pregunta. Proporcionó algo más de información. – bytebiscuit

+0

Parece que el encabezado de longitud de contenido está equivocado. Además, si todo lo que hace es leer los datos y volcarlos en un archivo, no necesita envolver el flujo de entrada en un BufferedInputStream. Ya estás usando tu propio búfer y el doble buffer así solo agrega sobrecarga. No debería afectar nada, pero intente deshacerse de esa envoltura. –

+0

la longitud del contenido está bien, obtengo el tamaño correcto del archivo que 5171472 (~ 5.2MB) – bytebiscuit

Cuestiones relacionadas