[Metodos] Comprimir/Descomprimir un archivo ZIP (Parte II)

Descomprimir un archivo ZIP

Para descomprimir un Fichero ZIP(Puede ser rar) vamos a hacer uso de las siguientes clases java:
  1. Empezamos creando un objeto de la clase FileInputStream:
    • public FileInputStream(String name) throws FileNotFoundException
    • Crea un FileInputStream abriendo una conexión con un archivo real, el archivo viene dado por su ruta en el sistema.
      Un nuevo objeto FileDescriptor se crea para representar a este respecto archivo. En primer lugar, si hay un controlador de seguridad, su método checkRead(String name) se llama con el argumento dado como su propio argumento.
      Si no existe el archivo llamado, es un directorio en lugar inalcanzable, o por alguna otra razón no se pueden abrir para leer a continuación, un FileNotFoundException es lanzada.
    • Parámetros:
    • String name - Cadena de texto con la ruta el archivo Zip a descomprimir(Tiene que existir)
    • Arroja:
    • FileNotFoundException - si no existe el archivo, es un directorio sin permisos para java, o por alguna otra razón no se pueden abrir para la lectura.
      SecurityException - si existe un administrador de seguridad y su método checkRead() niega el acceso de lectura al archivo.

  2. Luego crearemos el objeto ZipInputStream, pasando como parámtro el FileInputStream creado anteriormente:
    • public ZipInputStream(InputStream in)
    • Crea un nuevo ZIPinput stream.
      La codificación UTF-8 es usadad para decodificar la entrada de nombres.
    • Parámetros:
    • InputStream in - Pasamos el FileInputStream, clase hija de InputStream.

  3. Creamos el objeto ZipEntry sin instanciarlo. Lo usaremos para ir obteniendo cada archivo que contenga el ZIP existente.

  4. Creamos un ciclo While, para ir recorriendo todo el contenido del ZIP. La condicion, será que el objeto ZipInputStream a través de su método "getNextEntry()" va a ir obteniendo los archivos comprimidos hasta ser nulo.
    • public ZipEntry getNextEntry() throws IOException
    • Lee la siguiente entrada del archivo ZIP y posiciona el flujo(Stream) al comienzo de los datos de entrada.
    • Devuelve:
    • Un objeto ZipEntry que es la siguiente entrada del archivo de ZIP, o "null" si no hay más entradas.
    • Arroja:
    • ZipException - si se ha producido un error de archivo ZIP
      IOException - si se ha producido un error de E / S

  5. En este punto, obtendremos todos los archivos comprimidos que contenga el ZIP. Los descomprimiremos con FileOutputStream
    • public FileOutputStream(String name) throws FileNotFoundException
    • Crea un flujo de salida de archivo para escribir en el archivo con el nombre especificado. Un nuevo objeto FileDescriptor se crea para representar a este respecto archivo.
      En primer lugar, si hay un controlador de seguridad, su método checkWrite(String name) se denomina con el nombre como el argumento dado.
      Si el archivo existe, pero es un directorio que java no puede acceder, o no existe, pero no se puede crear, o no se puede abrir por cualquier otra razón, entonces un FileNotFoundException es lanzada.
    • Parámetros:
    • String name - Cadena de texto con la ruta específica, para lo cual le pedimos a el objeto ZipEntry su nombre: "entrada.getName()"
    • Arroja:
    • FileNotFoundException - si el archivo existe, pero es un directorio en lugar sin acceso, o no existe, pero no se puede crear, o no se puede abrir por cualquier otra razón.
      SecurityException - si existe un administrador de seguridad y su método checkWrite niega el acceso de escritura al archivo.

  6. Ahora, ZipInputStream ira descomprimiendo a través de un metodo heredado de FilterInputStream read(byte[] b), para el cual crearemos previamente un array de byte con el tamaño que deseamos que será la dimensión de la lectura, y este método devuelve un entero (int) que almacenaremos en otra variable que crearemos también:
    • public int read(byte[] b) throws IOException
    • Lee hasta la longitud del array bytes dado por parámtro de esta entrada.
      Este método se bloquea hasta que alguna entrada está disponible.
      Este método simplemente realiza la llamada a read(b, 0, b.length) y devuelve el resultado. Es importante que no hace in.read(b) en su lugar; ciertas subclases de FilterInputStream dependen de la estrategia de aplicación efectivamente a utilizarse.
    • Parámetros:
    • byte[] b - Un buffer dentro del cual la informacion es leida.
    • Devuelve:
    • int entero - Un entero que es el número total de bytes leídos en la memoria intermedia, o menos uno (-1) si no hay más datos debido a que el final de la secuencia ha sido alcanzado. Este retorno lo almacenamos en una variable del tipo intenger.
    • Arroja:
    • IOException - Si un erro de Entrada/Salida occure.

  7. Para todas las lecturas del ZipInputStream, Dentro de un ciclo While, donde la condicion sea que siga habiendo datos, es decir el resultado del método debe ser mayor a cero, El FileOutputStream ira escribiendo con su método:
    • public void write(byte[] b,
      int off,
      int len)
      throws IOException
    • Escribe el tamaño dado en "len" de bytes en el array de bytes especificado comenzando en el desplazamiento fuera de este FileOutputStream.
    • Parámetros:
    • byte[] b - los datos.
      int off - el desplazamiento inicial de los datos.
      int len - el número de bytes para escribir.
    • Arroja:
    • IOException - Si un erro de Entrada/Salida occure.

  8. Procedemos a cerrar el FileOutputStream y el ZipInputStream con sus métodos close() y closeEntry() respectivamente.

  9. Ahora estamos listos para hacer lo que fuere con el archivo descomprimido, con la ruta:
    • entrada.toString();
    • Al final del while, deberemos cerrar el stream de ZipInputStream con su método close().

Mi pseudoCodógido es:

FileInputStream fis = new FileInputStream(nombreZip);
ZipInputStream zis = new ZipInputStream(fis);

ZipEntry entrada;
while (null != (entrada = zis.getNextEntry())) {
FileOutputStream fos = new FileOutputStream(entrada.getName());

int leido;
byte[] buffer = new byte[1024];
while (0 < (leido = zis.read(buffer))) {
fos.write(buffer, 0, leido);
}
fos.close();
zis.closeEntry();

//TODO manejar archivo
}
zis.close();

Para mi ejemplo, tenia el archivo de texto, que se maneja con las clases File, FileReader y BufferedReader, comprimido en zip para descomprimir y ese archivo de texto se muestra por pantalla con un metodo creado llamado: leerTXT(String rutaEspecifica)
Contenido en un método para ser llamado podria ser:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public static void mostrarZIP(String archivo, String nombreZip) {
    try {
        FileInputStream fis = new FileInputStream(nombreZip);
        ZipInputStream zis = new ZipInputStream(fis);

        ZipEntry entrada;
        while (null != (entrada = zis.getNextEntry())) {
            System.out.println(entrada.toString());
            if (entrada.toString().contains(archivo)) {
                FileOutputStream fos = new FileOutputStream(entrada.getName());

            int leido;
            byte[] buffer = new byte[1024];
            while (0 < (leido = zis.read(buffer))) {
                fos.write(buffer, 0, leido);
            }
            fos.close();
            zis.closeEntry();
            LeerEscribir.leerTXT(entrada.toString());
            }
        }
        zis.close();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

Donde la clase LeerEscribir y el metodo leerTXT es del post [Metodos] Leer y Escribir un archivo de texto.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public static void leerTXT(String rutaEspecifica) {
    String cadena;
    File archivo = new File(rutaEspecifica);
    if (archivo.exists()) {
        try {
            FileReader fr = new FileReader(archivo);
            BufferedReader br = new BufferedReader(fr);

            while ((cadena = br.readLine()) != null) {
                System.out.println(cadena);
            }

            br.close();
            fr.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    } else {
        System.err.println("El sistema no pudo hallar la ruta especifica.");
    }
}

Una llamada a este método, que no tiene que ser de clase, podria ser:

mostrarZIP("C:\\blog\\archivoTexto.txt", "C:\\blog\\mizipExistente.zip");


No hay comentarios:

Publicar un comentario