Join FlipAndroid.COM Telegram Group: https://t.me/joinchat/F_aqThGkhwcLzmI49vKAiw


Java.io.FileNotFoundException: Este archivo no se puede abrir como descriptor de archivo; Probablemente está comprimido

Estoy programando una caja de resonancia de android. El problema es que algunos sonidos funcionan, y algunos no funcionan. Aquí está el rastreo que obtengo por los sonidos que no funciona

05-31 13:23:04.227 18440 18603 W System.err: java.io.FileNotFoundException: This file can not be opened as a file descriptor; it is probably compressed 05-31 13:23:04.227 18440 18603 W System.err: at android.content.res.AssetManager.openAssetFd(Native Method) 05-31 13:23:04.227 18440 18603 W System.err: at android.content.res.AssetManager.openFd(AssetManager.java:331) 05-31 13:23:04.227 18440 18603 W System.err: at com.phonegap.AudioPlayer.startPlaying(AudioPlayer.java:201) 05-31 13:23:04.227 18440 18603 W System.err: at com.phonegap.AudioHandler.startPlayingAudio(AudioHandler.java:181) 05-31 13:23:04.235 18440 18603 W System.err: at com.phonegap.AudioHandler.execute(AudioHandler.java:64) 05-31 13:23:04.235 18440 18603 W System.err: at com.phonegap.api.PluginManager$1.run(PluginManager.java:86) 05-31 13:23:04.235 18440 18603 W System.err: at java.lang.Thread.run(Thread.java:1096) 

¿algunas ideas?

5 Solutions collect form web for “Java.io.FileNotFoundException: Este archivo no se puede abrir como descriptor de archivo; Probablemente está comprimido”

Hay limitaciones en la apertura de archivos comprimidos en la carpeta de activos. Esto se debe a que los archivos sin comprimir pueden ser directamente mapeados en el espacio de direcciones virtual de los procesos, evitando así la necesidad de la misma cantidad de memoria para la descompresión.

El manejo de la compresión de activos en aplicaciones de Android discute algunas técnicas para tratar archivos comprimidos. Usted puede engañar aapt en no comprimir el archivo mediante una extensión que no está comprimido (por ejemplo, mp3 ) o puede agregar manualmente a la apk sin compresión en lugar de obtener aapt para hacer el trabajo.

Puede desactivar la compresión de activos para ciertas extensiones de la siguiente manera:

 android { aaptOptions { noCompress "pdf" } } 

Fuente

Esta situación decididamente irritante se produce porque cuando se construye .apk , algunos recursos se comprimen antes de almacenarlos, mientras que otros se tratan como ya comprimidos (por ejemplo, imágenes, video) y se dejan solos. El último grupo se puede abrir con openAssetFd , el primer grupo no puede – si lo intenta, obtiene el error "Este archivo no se puede abrir como descriptor de archivo, probablemente se comprime".

Una opción es engañar al sistema de compilación para que no comprima los recursos (ver el enlace en la respuesta de @nicstrong), pero esto es complicado. Es mejor tratar de resolver el problema de una manera más predecible.

La solución que AssetFileDescriptor utiliza el hecho de que mientras que no puede abrir un AssetFileDescriptor para el activo, todavía puede abrir un InputStream . Puede utilizar esto para copiar el elemento en el caché de archivos de la aplicación y, a continuación, devolver un descriptor para ello:

 @Override public AssetFileDescriptor openAssetFile(final Uri uri, final String mode) throws FileNotFoundException { final String assetPath = uri.getLastPathSegment(); // or whatever try { final boolean canBeReadDirectlyFromAssets = ... // if your asset going to be compressed? if (canBeReadDirectlyFromAssets) { return getContext().getAssets().openFd(assetPath); } else { final File cacheFile = new File(getContext().getCacheDir(), assetPath); cacheFile.getParentFile().mkdirs(); copyToCacheFile(assetPath, cacheFile); return new AssetFileDescriptor(ParcelFileDescriptor.open(cacheFile, MODE_READ_ONLY), 0, -1); } } catch (FileNotFoundException ex) { throw ex; } catch (IOException ex) { throw new FileNotFoundException(ex.getMessage()); } } private void copyToCacheFile(final String assetPath, final File cacheFile) throws IOException { final InputStream inputStream = getContext().getAssets().open(assetPath, ACCESS_BUFFER); try { final FileOutputStream fileOutputStream = new FileOutputStream(cacheFile, false); try { //using Guava IO lib to copy the streams, but could also do it manually ByteStreams.copy(inputStream, fileOutputStream); } finally { fileOutputStream.close(); } } finally { inputStream.close(); } } 

Esto significa que su aplicación dejará los archivos de caché mintiendo, pero eso está bien. Tampoco intenta volver a usar los archivos de caché existentes, que quizá no le importen.

Sólo debe obtener esta excepción si intenta abrir FileDesriptor . Por sólo leer el archivo puede ir a través del InputStream ( AssetManager.open("filename.ext") ). Esto funcionó para mí.

Si necesita el tamaño del archivo por adelantado, necesita el FileDescriptor (y por lo tanto un archivo sin comprimir) para llamar a su método getLength() , de lo contrario tiene que leer el flujo completo para determinar su tamaño.

He hecho un paseo alrededor, yo uso:

 ParcelFileDescriptor mFileDescriptor = context.getAssets().openFd(file).getParcelFileDescriptor(); 

Pero ese retorno: java.io.FileNotFoundException: Este archivo no se puede abrir como descriptor de archivo; Probablemente está comprimido.

En lugar de esta implementación abre el archivo directamente usando las funciones form ParcelFileDescriptor.

 private void openRenderer(Context context,String fileName) throws IOException { File file= FileUtils.fileFromAsset(context, fileName); ParcelFileDescriptor parcelFileDescriptor = ParcelFileDescriptor.open(file,ParcelFileDescriptor.MODE_READ_WRITE); mPdfRenderer = new PdfRenderer(parcelFileDescriptor); }` public class FileUtils { private FileUtils() { } public static File fileFromAsset(Context context, String assetName) throws IOException { File outFile = new File(context.getCacheDir(), assetName ); copy(context.getAssets().open(assetName), outFile); return outFile; } public static void copy(InputStream inputStream, File output) throws IOException { FileOutputStream outputStream = null; try { outputStream = new FileOutputStream(output); boolean read = false; byte[] bytes = new byte[1024]; int read1; while((read1 = inputStream.read(bytes)) != -1) { outputStream.write(bytes, 0, read1); } } finally { try { if(inputStream != null) { inputStream.close(); } } finally { if(outputStream != null) { outputStream.close(); } } } } } 
FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.