Unzip a folder from java

1

I need to unzip a folder from java however the class does not work for me

package controlador;
import java.io.BufferedInputStream;  
import java.io.BufferedOutputStream;  
import java.io.FileInputStream;  
import java.io.FileOutputStream;
import java.util.zip.ZipInputStream;

public class Descomprime {  
       public void Descomprimir (String c, String d )throws Exception{

    ZipInputStream entrada = new ZipInputStream(new BufferedInputStream(new FileInputStream(c)));
    if(entrada.getNextEntry()==null)
    {
        int leido;
        byte []buffer = new byte [4758];
        BufferedOutputStream salida = new BufferedOutputStream(new FileOutputStream(d),4758);
        while((leido = entrada.read(buffer, 0, 4758))!=1)
            salida.write(buffer, 0, leido);
            salida.flush();
            salida.close();
            entrada.close();
        }
    }
}

I get an error in the line

BufferedOutputStream salida = new BufferedOutputStream(new FileOutputStream(d),4758);
    while((leido = entrada.read(buffer, 0, 4758))!=1)
    introducir el código aquí
    
asked by Jeferson Martinez 09.09.2016 в 23:27
source

1 answer

1

You are confusing Zip flow (ZipInputStream) with entries (ZipEntry). The correct thing would be to save the entry in a variable and act when it is different from null, not when it is the same:

    ZipInputStream flujo = new ZipInputStream(new BufferedInputStream(
                             new FileInputStream(c)));
    ZipEntry entrada = flujo.getNextEntry();
    if ( entrada != null) {

On the line:

while ((leido = entrada.read(buffer, 0, 4758)) != 1)

input.read returns the number of bytes read or -1 if the end of the entry has been reached. When it returns -1 this causes the exception on the line:

            salida.write(buffer, 0, leido);

when asking to type -1 bytes.

The correct thing would be to compare that it is not -1:

while ((leido = entrada.read(buffer, 0, 4758)) != -1)

Also keep in mind that a ZIP can contain folders as well as files. We can not just treat all entries as if they were files.

        if (entrada.isDirectory()) {
            File directorio = new File(nombreSalida);
            directorio.mkdir();
        }

Finally, a ZIP can contain several files (entries or entries), so an if is not enough, you have to go through them in a loop to get all the files and unzip them. The following is the complete code:

package controlador;

import java.io.BufferedInputStream;
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;

public class Descomprime {

  public void Descomprimir(String ficheroZip, String directorioSalida)
          throws Exception {
    final int TAM_BUFFER = 4096;
    byte[] buffer = new byte[TAM_BUFFER];

    ZipInputStream flujo = null;
    try {
      flujo = new ZipInputStream(new BufferedInputStream(
              new FileInputStream(ficheroZip)));
      ZipEntry entrada;
      while ((entrada = flujo.getNextEntry()) != null) {
        String nombreSalida = directorioSalida + File.separator
                + entrada.getName();
        if (entrada.isDirectory()) {
          File directorio = new File(nombreSalida);
          directorio.mkdir();
        } else {
          BufferedOutputStream salida = null;
          try {
            int leido;
            salida = new BufferedOutputStream(
                    new FileOutputStream(nombreSalida), TAM_BUFFER);
            while ((leido = flujo.read(buffer, 0, TAM_BUFFER)) != -1) {
              salida.write(buffer, 0, leido);
            }
          } finally {
            if (salida != null) {
              salida.close();
            }
          }
        }
      }
    } finally {
      if (flujo != null) {
        flujo.close();
      }

    }
  }
}

I have taken the liberty of changing the size of the buffer by a round number (in binary). But regardless of the number used it is not recommended to repeat it for several code sites, better define a constant and use that constant in the code.

    
answered by 10.09.2016 / 09:46
source