2010-10-20 15 views
14

mi aplicación descarga un archivo zip con aproximadamente 350 archivos. Una mezcla de archivos JPG y HTML. La función que escribí para hacerlo funciona bien, pero la descompresión tarda para siempre. Al principio pensé que la razón podría ser que escribir en la tarjeta SD es lento. pero cuando descomprimo el mismo archivo comprimido con otra aplicación en mi teléfono, funciona mucho más rápido. ¿Hay algo que pueda hacer para optimizarlo?Extrakting Zip to SD-Card es muy lento. ¿Cómo puedo optimizar el rendimiento?

Aquí está el código:

private void extract() { 

    try { 
     FileInputStream inStream = new FileInputStream(targetFilePath); 
     ZipInputStream zipStream = new ZipInputStream(new BufferedInputStream(inStream)); 
     ZipEntry entry; 
     ZipFile zip = new ZipFile(targetFilePath); 

        //i know the contents for the zip so i create the dirs i need in advance 
     new File(targetFolder).mkdirs(); 
     new File(targetFolder + "META-INF").mkdir(); 
     new File(targetFolder + "content").mkdir(); 

     int extracted = 0; 

     while((entry = zipStream.getNextEntry()) != null) { 
      if (entry.isDirectory()) { 
       new File(targetFolder + entry.getName()).mkdirs(); 
      } else { 
       FileOutputStream outStream = new FileOutputStream(targetFolder + entry.getName()); 
       for (int c = zipStream.read(); c != -1; c = zipStream.read()) { 
        outStream.write(c); 
       } 
       zipStream.closeEntry(); 
       outStream.close(); 

       extracted ++; 
      } 

      publishProgress(""+(int)extracted*100/zip.size()); 
     } 

     zipStream.close(); 
     inStream.close(); 
     // 
     new File(targetFilePath).delete(); 
    } catch (FileNotFoundException e) { 
     e.printStackTrace(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
} 

gracias a CommonsWare he modificado mi código como este:

    int size; 
       byte[] buffer = new byte[2048]; 

       FileOutputStream outStream = new FileOutputStream(targetFolder + entry.getName()); 
       BufferedOutputStream bufferOut = new BufferedOutputStream(outStream, buffer.length); 

       while((size = zipStream.read(buffer, 0, buffer.length)) != -1) { 
        bufferOut.write(buffer, 0, size); 
       } 

       bufferOut.flush(); 
       bufferOut.close(); 

gran diferencia de rendimiento. Muchas gracias.

Respuesta

14

Estás leyendo y escribiendo un byte a la vez. Considere leer y escribir un bloque más grande a la vez.

+1

GRACIAS! Eso realmente hizo el truco. – notme

+1

El enlace proporcionado en esta respuesta no funciona. –

+0

@CommonsWare El enlace está caído, ¿podría corregirlo? – Scorchio

0

Solo use este método una vez y créame que es un proceso súper rápido. Descomprimirá todos los archivos sin saltarse ningún archivo en 1 segundo.

public boolean rajDhaniSuperFastUnzip(String inputZipFile, String destinationDirectory) 
     { 
    try { 
     int BUFFER = 2048; 
     List<String> zipFiles = new ArrayList<String>(); 
     File sourceZipFile = new File(inputZipFile); 
     File unzipDestinationDirectory = new File(destinationDirectory); 
     unzipDestinationDirectory.mkdir(); 
     ZipFile zipFile; 
     zipFile = new ZipFile(sourceZipFile, ZipFile.OPEN_READ); 
     Enumeration<?> zipFileEntries = zipFile.entries(); 
     while (zipFileEntries.hasMoreElements()) { 
      ZipEntry entry = (ZipEntry) zipFileEntries.nextElement(); 
      String currentEntry = entry.getName(); 
      File destFile = new File(unzipDestinationDirectory, currentEntry); 
      if (currentEntry.endsWith(".zip")) { 
       zipFiles.add(destFile.getAbsolutePath()); 
      } 

      File destinationParent = destFile.getParentFile(); 

      destinationParent.mkdirs(); 

      try { 
       if (!entry.isDirectory()) { 
        BufferedInputStream is = 
          new BufferedInputStream(zipFile.getInputStream(entry)); 
        int currentByte; 
        byte data[] = new byte[BUFFER]; 

        FileOutputStream fos = new FileOutputStream(destFile); 
        BufferedOutputStream dest = 
          new BufferedOutputStream(fos, BUFFER); 
        while ((currentByte = is.read(data, 0, BUFFER)) != -1) { 
         dest.write(data, 0, currentByte); 
        } 
        dest.flush(); 
        dest.close(); 
        is.close(); 
       } 
      } catch (IOException ioe) { 
       ioe.printStackTrace(); 
      } 
     } 
     zipFile.close(); 

     for (Iterator<String> iter = zipFiles.iterator(); iter.hasNext();) { 
      String zipName = (String)iter.next(); 
      doUnzip(
       zipName, 
       destinationDirectory + 
        File.separatorChar + 
        zipName.substring(0,zipName.lastIndexOf(".zip")) 
      ); 
     } 
    } catch (IOException e) { 
     e.printStackTrace(); 
     return false ; 
    } 
    return true; 
} 

Hope esto le ayudará a .. :) Feliz Codificación