una - comprimir varios archivos en un zip con java
Cómo crear un archivo Zip sin comprimir en Java (3)
Estoy usando el paquete de utilidades Zip de Java y quería saber cómo crear un archivo zip sin compresión. Poner el nivel a 0 no ayuda. ¿Es esto correcto?
Además, cuando utilicé el método STORED
, arroja la siguiente excepción:
java.util.zip.ZipException: STORED entry missing size, compressed size, or crc-32
Puedo establecer el tamaño pero ahora se lanza la siguiente excepción:
java.util.zip.ZipException: invalid entry crc-32
Simplemente estoy siguiendo todos los ejemplos disponibles al buscar en la web y no puedo entenderlo realmente, supongo. Sería genial si alguien me puede ayudar en esto y me dé sugerencias para corregir el problema que podría estar haciendo.
Estoy desconfiado de la solución de aperitivos (desde que se eliminó), pero sé por qué funcionó La línea (que desde entonces ha sido corregida en su respuesta)
zipOut.setLevel(ZipOutputStream.STORED); // accidentally right
estaba utilizando el valor estático ZipOutputStream.STORED
, que coincidentemente es igual a 0
. Entonces, lo que está haciendo esa línea es establecer el nivel usado por el método DEFLATED predeterminado en compresión cero (esto es obviamente lo que quieres hacer, pero solo funcionó por suerte). Entonces, para obtener lo que desea de forma explícita y segura, use esto en su lugar:
zipOut.setMethod(ZipOutputStream.DEFLATED); // this line optional
zipOut.setLevel(0);
o
zipOut.setLevel(Deflater.NO_COMPRESSION);
Si utiliza
zipOut.setMethod(ZipOutputStream.STORED);
zipOut.setLevel(Deflater.NO_COMPRESSION);
probablemente obtendrás la excepción que Keya anotó en la pregunta original. Creo que Christian Schlichtherle tiene razón; está recibiendo las Excepciones porque no está configurando el CRC en la entrada. La repercusión de esto es que para usar el método ALMACENADO, primero debe leer todo el archivo de entrada, o encontrar alguna otra forma de establecer el tamaño, el tamaño comprimido (debe ser igual) y el CRC antes de llamar a zipOut.putNextEntry()
. De lo contrario, se encontrará con más excepciones si sobrepasa el atributo de tamaño escribiendo demasiados bytes en el flujo de salida. Parece que las especificaciones ZIP dicen que si está escribiendo datos ALMACENADOS, entonces tiene que escribir el encabezado [que incluye el CRC-32 y la longitud] "al principio" antes de los datos en sí, por lo tanto, la API de Java que los requiere se debe configurar antes de puede comenzar, ya que básicamente solo admite la transmisión al archivo zip final.
Para tu información:
En JDK Fuente del método [java.util.zip.ZipOutputStream.setLevel (int)]:
public void setLevel(int level) {
def.setLevel(level);
}
Simplemente redirige la configuración del nivel de compresión a la variable de campo [def], que es una instancia de [java.util.zip.Deflater].
Y en el código fuente de la clase [java.util.zip.Deflater]:
/**
* Compression level for no compression.
*/
public static final int NO_COMPRESSION = 0;
/**
* Compression level for fastest compression.
*/
public static final int BEST_SPEED = 1;
/**
* Compression level for best compression.
*/
public static final int BEST_COMPRESSION = 9;
/**
* Default compression level.
*/
public static final int DEFAULT_COMPRESSION = -1;
Entonces, creo que será más legible si usa el valor constante [Deflater.NO_COMPRESSION]:
zipOut.setMethod(ZipOutputStream.DEFLATED);
zipOut.setLevel(Deflater.NO_COMPRESSION);
crc32
usar el método STORED
, pero esto requiere que establezca las propiedades size
, compressedSize
y crc32
de la ZipEntry
correspondiente antes de poder llamar a putNextEntry
en ZipOutputStream
. Puede Crc32OutputStream
el CRC-32 utilizando un Crc32OutputStream
.