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.