2012-04-20 33 views
6

Tengo una aplicación que muestra imágenes GIF. Todo funciona bien si la imagen se guarda en dibujable, y acceder a ella como estoIOException - No se puede cargar el archivo

is=context.getResources().openRawResource(R.drawable.mygif); 
movie = Movie.decodeStream(is); 

pero necesito para descargar la imagen desde Internet, por lo que estoy guardándolo en CacheDir, que trabaja muy bien. Intenté lo siguiente para leerlo.

try 
    { 
     is = new BufferedInputStream(new FileInputStream(new File(context.getCacheDir(), "mygif.gif"))); 
    } 
    catch (FileNotFoundException e) 
    { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
    movie = Movie.decodeStream(is); 

Y esto

movie = Movie.decodeFile(new File(context.getCacheDir(), "mygif.gif").getPath()); 

Pero no importa qué, que termina con

java.io.IOException 
at java.io.InputStream.reset(InputStream.java:218) 
at android.graphics.Movie.decodeStream(Native Method) 
at android.graphics.Movie.decodeTempStream(Movie.java:74) 
at android.graphics.Movie.decodeFile(Movie.java:59) 

o

java.io.IOException: Mark has been invalidated. 
at java.io.BufferedInputStream.reset(BufferedInputStream.java:350) 
at android.graphics.Movie.decodeStream(Native Method) 

creo que es un error muy simple, pero no puedo superarlo. Manifiesto tiene:

<uses-permission android:name="android.permission.INTERNET"/> 
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> 
+0

Debe comprobar si la parte de descarga y almacenamiento está dañando el archivo. Después de que la aplicación descargue el archivo, puede sacarlo del emulador o dispositivo usando 'adb pull '. Luego puede verificar si es exactamente lo que hay en el servidor. –

+0

Lo saqué del emulador, y está bien. La imagen es 13kB si de alguna manera es importante –

+0

¿Ha intentado 'Movie.decodeFile (nuevo archivo (context.getCacheDir()," mygif.gif "). GetAbsolutePath())'? –

Respuesta

13

sugerencia:

1.try mover la ubicación de descarga a otra carpeta como: sdcard, o la aplicación de otra carpeta, excepto el cache.

2.when init el inputstream, trate de uso: init con un tamaño de búfer

int buffersize = 16*1024; 
InputStream is = new BufferedInputStream(xxx,buffersize); 

3.to comprobar el archivo existente en la carpeta de

cambio: cambiar el código como este y no uso Movie.decodeFile

InputStream is = null; 
    try { 
     is = new BufferedInputStream(new FileInputStream(new File(getCacheDir(), "mygif.gif")), 16 * 1024); 
     is.mark(16 * 1024); 
    } catch (FileNotFoundException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
movie = Movie.decodeStream(is); 

sin excepción tiro, y el movie no es nulo.

Además, aunque su código arrojará la excepción, el movie tampoco es nulo.

+0

1. No hay diferencia; 2. Sin diferencia; 3. Existe y no está corrupto –

+0

actualice la respuesta, por favor verifique. – idiottiger

+0

Gracias, el siguiente código hace el trabajo! mark() faltaba. Muchas gracias –

2

lo que sé es un post muy viejo, pero yo estaba teniendo el mismo problema

Copiar la InputStream a una matriz de bytes y llamando Movie.decodeByteArray trabajó para mí, incluso en dispositivos Samsung

0

Mi respuesta es basado en la respuesta de BeNeXuS.

El tamaño del archivo no siempre se conoce, consulte:

File file = ...; 
InputStream inputStream = new FileInputStream(file); 

o

InputStream inputStream = getContext().getContentResolver().openInputStream(uri); 

Después de conseguir el flujoEntrada:

BufferedInputStream bis = new BufferedInputStream(inputStream); 
ByteArrayOutputStream baos = new ByteArrayOutputStream(); 

byte buffer[] = new byte[1024]; 
int len; 
while ((len = bis.read(buffer, 0, buffer.length)) > 0) { 
    baos.write(buffer, 0, len); 
} 
bis.close(); 

byte[] imageData = baos.toByteArray(); 
baos.close(); 

Bitmap bitmap = BitmapFactory.decodeByteArray(imageData, 0, imageData.length); 
0

Android hasta 4,4 logra decodificar Película de File y Stream en caso de IOException interna en el método InputStream.reset(). Pero decodificar desde bytes funciona bien en todas las versiones de Android.Aquí hay una versión bastante mínima del código para hacer esto:

int size = (int) imageFile.length(); 
byte[] buffer = new byte[size]; 
FileInputStream inputStream = new FileInputStream(imageFile); 
int readLength = inputStream.read(buffer); 
inputStream.close(); 
Movie movie = Movie.decodeByteArray(buffer, 0, readLength); 
Cuestiones relacionadas