¿Cómo acelerar el tiempo de descompresión en Java / Android?

Descomprimir archivos en Android parece ser terriblemente lento. Al principio pensé que esto era solo el emulador, pero parece ser el mismo en el teléfono. He intentado diferentes niveles de compresión y, finalmente, he bajado al modo de almacenamiento, pero todavía toma años.

De todos modos, debe haber una razón! ¿Alguien más tiene este problema? Mi método de descompresión se ve así:

public void unzip() { try{ FileInputStream fin = new FileInputStream(zipFile); ZipInputStream zin = new ZipInputStream(fin); File rootfolder = new File(directory); rootfolder.mkdirs(); ZipEntry ze = null; while ((ze = zin.getNextEntry())!=null){ if(ze.isDirectory()){ dirChecker(ze.getName()); } else{ FileOutputStream fout = new FileOutputStream(directory+ze.getName()); for(int c = zin.read();c!=-1;c=zin.read()){ fout.write(c); } //Debug.out("Closing streams"); zin.closeEntry(); fout.close(); } } zin.close(); } catch(Exception e){ //Debug.out("Error trying to unzip file " + zipFile); } } 

No sé si descomprimir en Android es lento, pero copiar bytes de bytes en un bucle seguramente lo está ralentizando aún más. Intente usar BufferedInputStream y BufferedOutputStream; puede ser un poco más complicado, pero en mi experiencia, al final vale la pena.

 BufferedInputStream in = new BufferedInputStream(zin); BufferedOutputStream out = new BufferedOutputStream(fout); 

Y luego puedes escribir con algo así:

 byte b[] = new byte[1024]; int n; while ((n = in.read(b,0,1024)) >= 0) { out.write(b,0,n); } 

Gracias por la solución Robert. Modifiqué mi método de unizip y ahora solo lleva unos pocos segundos en vez de 2 minutos. Quizás alguien esté interesado en mi solución. Así que aquí tienes:

 public void unzip() { try { FileInputStream inputStream = new FileInputStream(filePath); ZipInputStream zipStream = new ZipInputStream(inputStream); ZipEntry zEntry = null; while ((zEntry = zipStream.getNextEntry()) != null) { Log.d("Unzip", "Unzipping " + zEntry.getName() + " at " + destination); if (zEntry.isDirectory()) { hanldeDirectory(zEntry.getName()); } else { FileOutputStream fout = new FileOutputStream( this.destination + "/" + zEntry.getName()); BufferedOutputStream bufout = new BufferedOutputStream(fout); byte[] buffer = new byte[1024]; int read = 0; while ((read = zipStream.read(buffer)) != -1) { bufout.write(buffer, 0, read); } zipStream.closeEntry(); bufout.close(); fout.close(); } } zipStream.close(); Log.d("Unzip", "Unzipping complete. path : " + destination); } catch (Exception e) { Log.d("Unzip", "Unzipping failed"); e.printStackTrace(); } } public void hanldeDirectory(String dir) { File f = new File(this.destination + dir); if (!f.isDirectory()) { f.mkdirs(); } } 

Usando ideas anteriores e ideas de otras fonts, he creado esta clase

Crear esta nueva clase

 import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import android.util.Log; public class DecompressFast { private String _zipFile; private String _location; public DecompressFast(String zipFile, String location) { _zipFile = zipFile; _location = location; _dirChecker(""); } public void unzip() { try { FileInputStream fin = new FileInputStream(_zipFile); ZipInputStream zin = new ZipInputStream(fin); ZipEntry ze = null; while ((ze = zin.getNextEntry()) != null) { Log.v("Decompress", "Unzipping " + ze.getName()); if(ze.isDirectory()) { _dirChecker(ze.getName()); } else { FileOutputStream fout = new FileOutputStream(_location + ze.getName()); BufferedOutputStream bufout = new BufferedOutputStream(fout); byte[] buffer = new byte[1024]; int read = 0; while ((read = zin.read(buffer)) != -1) { bufout.write(buffer, 0, read); } bufout.close(); zin.closeEntry(); fout.close(); } } zin.close(); Log.d("Unzip", "Unzipping complete. path : " +_location ); } catch(Exception e) { Log.e("Decompress", "unzip", e); Log.d("Unzip", "Unzipping failed"); } } private void _dirChecker(String dir) { File f = new File(_location + dir); if(!f.isDirectory()) { f.mkdirs(); } } } 

USO

simplemente pase la ubicación del archivo zip y la ubicación de destino a esta clase
ejemplo

  String zipFile = Environment.getExternalStorageDirectory() + "/the_raven.zip"; //your zip file location String unzipLocation = Environment.getExternalStorageDirectory() + "/unzippedtestNew/"; // unzip location DecompressFast df= new DecompressFast(zipFile, unzipLocation); df.unzip(); 

No olvide agregar los siguientes permisos en el manifiesto (también Ejecute el permiso de tiempo si la versión es superior a marshmellow)

   

espero que esto ayude

La URL que me ayudó a aprender cómo comprimir y descomprimir se puede encontrar aquí .

Utilicé esa URL junto con la respuesta anterior del usuario3203118 para descomprimir. Esto es para futuras referencias de personas que se topan con este tema y necesitan ayuda para resolverlo.

A continuación se muestra el código de ZipManager que estoy usando:

 public class ZipManager { private static final int BUFFER = 80000; public void zip(String[] _files, String zipFileName) { try { BufferedInputStream origin = null; FileOutputStream dest = new FileOutputStream(zipFileName); ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream( dest)); byte data[] = new byte[BUFFER]; for (int i = 0; i < _files.length; i++) { Log.v("Compress", "Adding: " + _files[i]); FileInputStream fi = new FileInputStream(_files[i]); origin = new BufferedInputStream(fi, BUFFER); ZipEntry entry = new ZipEntry(_files[i].substring(_files[i] .lastIndexOf("/") + 1)); out.putNextEntry(entry); int count; while ((count = origin.read(data, 0, BUFFER)) != -1) { out.write(data, 0, count); } origin.close(); } out.close(); } catch (Exception e) { e.printStackTrace(); } } public void unzip(String _zipFile, String _targetLocation) { // create target location folder if not exist dirChecker(_targetLocation); try { FileInputStream fin = new FileInputStream(_zipFile); ZipInputStream zin = new ZipInputStream(fin); ZipEntry ze = null; while ((ze = zin.getNextEntry()) != null) { // create dir if required while unzipping if (ze.isDirectory()) { dirChecker(ze.getName()); } else { FileOutputStream fout = new FileOutputStream( _targetLocation + "/" + ze.getName()); BufferedOutputStream bufout = new BufferedOutputStream(fout); byte[] buffer = new byte[1024]; int read = 0; while ((read = zin.read(buffer)) != -1) { bufout.write(buffer, 0, read); } zin.closeEntry(); bufout.close(); fout.close(); } } zin.close(); } catch (Exception e) { System.out.println(e); } } private void dirChecker(String dir) { File f = new File(dir); if (!f.isDirectory()) { f.mkdirs(); } } } 

Simplemente llame a este método y le dará un mejor rendimiento.

  public boolean unzip(Context context) { try { FileInputStream fin = new FileInputStream(_zipFile); ZipInputStream zin = new ZipInputStream(fin); BufferedInputStream in = new BufferedInputStream(zin); ZipEntry ze = null; while ((ze = zin.getNextEntry()) != null) { Log.v("Decompress", "Unzipping " + ze.getName()); if (ze.isDirectory()) { _dirChecker(ze.getName()); } else { FileOutputStream fout = new FileOutputStream(_location + ze.getName()); BufferedOutputStream out = new BufferedOutputStream(fout); byte b[] = new byte[1024]; for (int c = in.read(b,0,1024); c != -1; c = in.read()) { out.write(b,0,c); } zin.closeEntry(); fout.close(); } } zin.close(); return true; } catch (Exception e) { Log.e("Decompress", "unzip", e); return false; } } private void _dirChecker(String dir) { File f = new File(_location + dir); if (!f.isDirectory()) { f.mkdirs(); } } 

En caso de utilizar BufferedOutputStream, asegúrese de enjuagarlo. Si no lo haces, el tamaño más pequeño que el búfer no se descomprimirá correctamente

 if (ze.isDirectory()) { _dirChecker(ze.getName()); } else { FileOutputStream fout = new FileOutputStream(_location + ze.getName()); BufferedOutputStream out = new BufferedOutputStream(fout); byte buffer[] = new byte[1024]; for (int c = in.read(buffer,0,1024); c != -1; c = in.read()) { out.write(buffer,0,c); } out.flush();//flush it...... zin.closeEntry(); fout.close(); }