FileOutputStream lanza FileNotFoundException al desabrochar

Estoy usando una clase que encontré a través de google para descomprimir un archivo .zip .. El archivo .zip contiene archivos y carpetas. El problema es que FileOutputStream throws FileNotFoundException .. Pero el archivo debe tomarse del archivo .zip así que ¿cómo puede existir previamente?
Aquí está el código que estoy usando en el AsyncTask :

 @Override protected Boolean doInBackground(String... params) { try { String zipFile = Path + FileName; FileInputStream fin = new FileInputStream(zipFile); ZipInputStream zin = new ZipInputStream(fin); ZipEntry ze = null; while ((ze = zin.getNextEntry()) != null) { if (ze.isDirectory()) { dirChecker(ze.getName()); } else { FileOutputStream fout = new FileOutputStream(Path + ze.getName()); // <-- crashes here while ((length = zin.read(buffer)) > 0) { fout.write(buffer, 0, length); publishProgress(length); } zin.closeEntry(); fout.close(); } } zin.close(); } catch (Exception e) { mProgressDialog.dismiss(); return false; } return true; } 

Otro AsyncTask que descarga el .zip:

 @Override protected Boolean doInBackground(String... params) { try { URL url = new URL(params[0]); URLConnection conexion = url.openConnection(); conexion.connect(); int lenghtOfFile = conexion.getContentLength(); File f = new File(Path+FileName); if(!f.exists()) { f.mkdirs(); if(!f.createNewFile()) { f.delete(); f.createNewFile(); } } InputStream input = new BufferedInputStream(url.openStream()); OutputStream output = new FileOutputStream(Path+FileName); byte data[] = new byte[1024]; long total = 0; while ((count = input.read(data)) != -1) { total += count; publishProgress((int)((total*100)/lenghtOfFile)); output.write(data, 0, count); } output.flush(); output.close(); input.close(); return true; } catch (Exception e) { e.printStackTrace(); e.getCause(); return false; } 

Recibo de nuevo el FileNotFoundExcpetion con (es un directorio) !.

FileOutputStream lanzará FileNotFoundException si los directorios implicados no existen. No veo ningún código de creación de directorio aquí, o incluso cualquier código para comprobar si Path existe, por lo que probablemente es lo que está pasando.

Consigo el FileNotFoundException otra vez con (es un directorio) error del mensaje.

 File f = new File(Path+FileName); f.mkdirs(); 

Intenta usar

 File directory = new File(Path); directory.mkdirs(); 

y entonces

 File file = new File(directory, FileName); 

En lugar de su código.

Su primera versión se basa en dirChecker( ) que no ha publicado, pero no funciona correctamente, o su archivo ZIP no contiene entradas de directorio en absoluto, que es prefectly legal, por lo que no debe confiar en ellos Estar presente de todos modos.

Tu segunda versión es mejor pero no necesitas todo esto:

  File f = new File(Path+FileName); if(!f.exists()) { f.mkdirs(); if(!f.createNewFile()) { f.delete(); f.createNewFile(); } } 

Sólo necesitas esto:

 File f = new File(Path, FileName); f.getParentFile().mkdirs(); 

El resto ocurrirá de todos modos.

Desde javadocs para el constructor FileOutputStream

Tiros:
FileNotFoundException – si el archivo existe, pero es un directorio en lugar de un archivo regular, no existe pero no se puede crear o no se puede abrir por cualquier otro motivo

A menudo, se produce una excepción FileNotFoundException si no tiene permisos para crear archivos o que parte del sistema de archivos es de sólo lectura (aunque no estoy seguro de en qué medida esto se aplica en Android)

El problema aquí es causado debido a archivos zip o directorios anidados dentro de la cremallera dada. En caso de que el ZipEntry dado es un directorio, es necesario crear el directorio y omitir la escritura con FileOutputStream.

zipEnrty.isDirectory() para comprobar si el zipEntry dado es un directorio y cree el directorio usando zipEntry.mkDirs() y proceda al siguiente zipEntry sin escribirlo usando fileOutputStream.

Aquí está el código completo para descomprimir un archivo zip:

 import java.io.*; import java.util.zip.*; public class Unzip { public static void main (String args[]) { try { final int BUFFER = 1024; int count; byte data[] = new byte[BUFFER]; String path="res/Example.zip"; BufferedOutputStream bufferedOutputStream = null; FileInputStream fileInputStream = new FileInputStream(path); ZipInputStream zipInputStream = new ZipInputStream(new BufferedInputStream(fileInputStream)); ZipEntry zipEntry; while((zipEntry = zipInputStream.getNextEntry()) != null) { System.out.println("Extracting: " +zipEntry); File file=new File(zipEntry.getName()); if(zipEntry.isDirectory()) { file.mkdirs(); continue; } FileOutputStream fileOutputStream = new FileOutputStream(file,false); bufferedOutputStream = new BufferedOutputStream(fileOutputStream, BUFFER); while ((count = zipInputStream.read(data, 0, BUFFER))!= -1) bufferedOutputStream.write(data, 0, count); bufferedOutputStream.flush(); bufferedOutputStream.close(); } zipInputStream.close(); } catch(Exception e) { e.printStackTrace(); } } } 

Solía ​​escribir desde el widget de la aplicación a la memoria interna y externa de Android con el código siguiente:

  URL adr = new URL(cleanUrl); HttpURLConnection urlConnection = (HttpURLConnection) adr.openConnection(); urlConnection.setRequestMethod("GET"); urlConnection.setDoOutput(true); urlConnection.setReadTimeout(5000); urlConnection.connect(); File file = new File(path, name); FileOutputStream fileOutput = new FileOutputStream(file); InputStream inputStream = urlConnection.getInputStream(); byte[] buffer = new byte[1024]; int bufferLength = 0; while ( (bufferLength = inputStream.read(buffer)) > 0 ) { fileOutput.write(buffer, 0, bufferLength); } fileOutput.flush(); fileOutput.close(); 

Donde el camino era ambos:

  path = mContext.getFilesDir(); 

o

  path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES); 

y

  path.mkdirs(); 

En ambos casos tengo una FileNotFoundException y un archivo creado con longitud cero.

He logrado escribir en ambos tipos de memoria de Android con una función siguiente:

  protected InputStream get(String url) throws ClientProtocolException, IOException { final HttpClient client = new DefaultHttpClient(); HttpGet getRequest = new HttpGet(url); HttpResponse response = client.execute(getRequest); if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) { return null; } final HttpEntity entity = response.getEntity(); if (entity != null) { try { return entity.getContent(); } catch (Exception e) { e.printStackTrace(); } } return null; } 

Y después del uso:

  File file = new File(path, name); FileOutputStream fileOutput = new FileOutputStream(file); InputStream inputStream = get(cleanUrl); byte[] buffer = new byte[1024]; int bufferLength = 0; while ( (bufferLength = inputStream.read(buffer)) > 0 ) { fileOutput.write(buffer, 0, bufferLength); } fileOutput.flush(); fileOutput.close(); 

Quite el "android: maxSdkVersion =" 18 "" de Manifest

 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="18"/> 

Usted declaró en el archivo de manifiesto.

  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 
  • Cómo personalizar backgroud, color de fondo y color de texto para Toast en android
  • ¿Cómo utilizar Flowable en RxJava 2?
  • Android: muestra el micrófono sin grabación para obtener la amplitud / nivel en vivo?
  • Dibujo sobre lienzo con pintura en mejor resolución? (Androide)
  • Cuando los métodos predeterminados serán compatibles (Java 8) en Android?
  • Envío de cadenas bluetooth en android
  • ¿Por qué estoy recibiendo una excepción de puntero nulo aunque hay valor show cuando println?
  • No se puede obtener ScrollView para desplazarse cuando se muestra el teclado virtual
  • Android no puede encontrar el método de símbolo getMap ()
  • Diferencia entre AAR, JAR, DEX, APK en Android
  • ¿Cómo puedo detener un temporizador?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.