"¡Hola, amigo!"

"¡Hola, Ellie!"

"Hoy vamos a estudiar flujos de E/S".

"Sí, ya sé todo sobre ellos. Usamos las clases FileInputStream y FileOutputStream aquí".

"Sí, ¿y cuál de los métodos de estas clases conoces?"

"Claro. Estos son los métodos de FileInputStream:"

Método Descripción
int read() Lee un byte y lo devuelve.
int read(byte b[]) Lee una matriz de bytes y la devuelve.
int read(byte b[], int off, int len) Lee una matriz de bytes de la secuencia.
long skip(long n) Salta n bytes, se usa cuando se lee de la secuencia.
int available() Devuelve el número de bytes que aún se pueden leer de la transmisión.
void close() Cierra la corriente.

"¡En el clavo! ¿Y los métodos de FileOutputStream?"

"Echar un vistazo:"

Método Descripción
void write(int b) Escribe un byte en la secuencia.
void write(byte b[]) Escribe una matriz de bytes en la secuencia.
void write(byte b[], int off, int len) Escribe una matriz de bytes en la secuencia.
void close() Cierra la corriente.

"¡Amigo, me sorprendes!"

"¡Y algo más!"

"Bien, entonces te daré dos clases nuevas: ZipInputStream y ZipOutputStream".

FileInputStream, FileOutputStream, ZipOutputStream, ZipInputStream - 1

"¿ Zip ? ¿Es como un archivo zip?"

"Exactamente. Estos flujos están diseñados para funcionar con archivos zip. ¡Puedes usarlos para leer o escribir directamente en un archivo zip!"

"¡Santo Dios! Qué interesante. Pero un archivo zip no puede tener un archivo, sino varios. ¿Cómo funcionan?"

"Para eso, hay otra clase especial: ZipEntry . Presenta un archivo almacenado en el archivo. Solo puede leer objetos ZipEntry de un ZipInputStream y solo puede escribir objetos ZipEntry en un ZipOutputStream . Pero resulta que puede leer y escriba en un ZipEntry como un archivo normal".

"¿Podría darme un ejemplo de cómo funciona?"

"Por supuesto. Aquí hay un ejemplo en el que creamos un archivo y colocamos un archivo en él:"

Código
// Create an archive
FileOutputStream zipFile = new FileOutputStream("c:/archive.zip");
ZipOutputStream zip = new ZipOutputStream(zipFile);

//Put a ZipEntry into it
zip.putNextEntry(new ZipEntry("document.txt"));

//Copy the file «document-for-archive.txt» to the archive under the name «document.txt»
File file = new File("c:/document-for-archive.txt");
Files.copy(file.toPath(), zip);

// Close the archive
zip.close();

"¡Qué interesante! ¿Y descomprimir archivos es igual de fácil?"

"Sí. Aquí hay una breve descripción de los métodos de las clases ZipEntry , ZipInputStream   y ZipOutputStream "

" ZipInputStream es una secuencia, por lo que todos los ZipEntry solo se pueden leer secuencialmente. Estos son sus métodos:"

Método Descripción
ZipEntry getNextEntry() Devuelve un objeto que describe la siguiente ZipEntry (se salta todos los bytes de la entrada actual).
void closeEntry() Cierra el flujo de entrada en el ZipEntry actual (omite todos los bytes en la entrada actual).
int available() Devuelve 1 si hay ZipEntries disponibles, de lo contrario 0.
int read(byte[] b, int off, int len) Lee bytes del ZipEntry actual.
long skip(long n) Salta n bytes al leer de la secuencia.
void close() Cierra la corriente.

"Realmente no entiendo".

"Lo mejor que puede hacer es imaginar que está leyendo un archivo de texto, y ZipEntries son como líneas en el archivo. Puede leer datos de la línea actual (el ZipEntry actual) o saltar de línea a línea ( getNextEntry , closeEntry ) ."

"Creo que entiendo, pero no estoy seguro".

"Aquí está ZipOutputStream y sus métodos:"

Método Descripción
void setComment(String comment) Establece un comentario en el archivo.
void setMethod(int method) Establece el método de compresión (tipo).
void setLevel(int level) Establece el nivel de compresión. Cuanto mayor sea la compresión, más lento va.
void putNextEntry(ZipEntry e) Agrega una nueva ZipEntry.
void closeEntry() Cierra el ZipEntry actual
void write(byte[] b, int off, int len) Escribe un conjunto de bytes en el ZipEntry actual.
void close() Cierra la corriente.

"Pero en el ejemplo anterior no usamos casi nada de esto".

"Estos son métodos opcionales. No tiene que especificar el nivel y el método de compresión; se usará la configuración predeterminada".

"Hmm. Eso no es tan malo. ¿Y ZipEntry?"

"Claro. La única otra información en un ZipEntry es la información de limpieza:"

Método Descripción
String getName(), setName(String) Archivo de nombre interno.
long getTime(), setTime(long) Última vez que se modificó la entrada.
long getCRC(), setCRC(long) Suma de comprobación.
long getSize(), setSize(long) Tamaño antes de la compresión.
int getMethod(), setMethod(int) Método de compresión.
long get/setCompressedSize() Tamaño después de cerrar con cremallera.
boolean isDirectory() ¿La entrada es un directorio?

"Eso no parece muy difícil. ¡Qué no hay que amar!"

"Excelente, entonces Diego también te dará tareas sobre este tema".

"Debería haber mantenido la boca cerrada".