Al tratar de comprimir un archivo usando el java.util.zip
tuve muchos problemas, la mayoría de los cuales resolví. Ahora que finalmente obtengo algo de salida, lucho por obtener la salida "correcta". Tengo un archivo ODT extraído (el directorio sería más adecuado para una descripción) al que hice algunas modificaciones. Ahora quiero comprimir ese directorio para recrear la estructura del archivo ODT. Comprimir el directorio y cambiarle el nombre para que termine con .odt funciona bien, así que no debería haber ningún problema.java.util.zip - Recreando la estructura de directorios
El problema principal es que pierdo la estructura interna del directorio. Todo se vuelve "plano" y no parece encontrar una manera de preservar la estructura original de varias capas. Agradecería algo de ayuda sobre esto ya que no puedo encontrar el problema.
Éstos son los fragmentos de código relevantes:
ZipOutputStream out = new ZipOutputStream(new FileOutputStream(
FILEPATH.substring(0, FILEPATH.lastIndexOf(SEPARATOR) + 1).concat("test.zip")));
compressDirectory(TEMPARCH, out);
El SEPARATOR
es el separador de archivos del sistema y el FILEPATH
es la ruta de archivo de la ODT original que voy a reemplazar, pero no he hecho aquí con fines de prueba. Simplemente escribo en un archivo test.zip en el mismo directorio.
private void compressDirectory(String directory, ZipOutputStream out) throws IOException
{
File fileToCompress = new File(directory);
// list contents.
String[] contents = fileToCompress.list();
// iterate through directory and compress files.
for(int i = 0; i < contents.length; i++)
{
File f = new File(directory, contents[i]);
// testing type. directories and files have to be treated separately.
if(f.isDirectory())
{
// add empty directory
out.putNextEntry(new ZipEntry(f.getName() + SEPARATOR));
// initiate recursive call
compressDirectory(f.getPath(), out);
// continue the iteration
continue;
}else{
// prepare stream to read file.
FileInputStream in = new FileInputStream(f);
// create ZipEntry and add to outputting stream.
out.putNextEntry(new ZipEntry(f.getName()));
// write the data.
int len;
while((len = in.read(data)) > 0)
{
out.write(data, 0, len);
}
out.flush();
out.closeEntry();
in.close();
}
}
}
El directorio que contiene los archivos zip es un lugar en el espacio de usuario y no en el mismo directorio que el archivo resultante. Supongo que esto podría ser un problema, pero realmente no puedo ver cómo. También calculé que el problema podría estar en usar la misma corriente para la salida, pero de nuevo no puedo ver cómo. Vi en algunos ejemplos y tutoriales que usan getPath()
en lugar de getName()
pero cambiar eso me da un archivo zip vacío.
Muchas gracias! Desgraciadamente, no veo cómo se conserva el formato de directorio original con tu código de compresión. En el ODT que uso hay directorios vacíos. Por lo que entiendo tu código, esos directorios nunca serán creados. ¿Me estoy perdiendo algo? – Eric
Los directorios son entradas vacías con un nombre que termina con '/'. He alterado el código. – McDowell
He adaptado la estructura de tu código y he abandonado las llamadas recursivas. Creo que fue la forma incorrecta de ver esto. El código funciona sin problemas con una excepción; Agrega carpetas vacías a la mayoría de los directorios secundarios, incluso si no están vacíos. Descubrí que eliminar la siguiente línea resuelve el problema: name = name.endsWith ("/")? nombre: nombre + "/"; Sospecho que al agregar un directorio al agregar la "\" también se crea una carpeta vacía dentro. Simplemente dejando que ZipEntries se ocupe de la construcción de la estructura, todo parece estar bien. ¡Gracias por toda tu ayuda! – Eric