Tengo un archivo de texto dinámico que recoge el contenido de una base de datos de acuerdo con la consulta del usuario. Tengo que escribir este contenido en un archivo de texto y comprimirlo en una carpeta en un servlet. ¿Cómo debería hacer esto?
StringBuilder sb =newStringBuilder();
sb.append("Test String");File f =newFile("d:\\test.zip");ZipOutputStream out =newZipOutputStream(newFileOutputStream(f));ZipEntry e =newZipEntry("mytext.txt");
out.putNextEntry(e);byte[] data = sb.toString().getBytes();
out.write(data,0, data.length);
out.closeEntry();
out.close();
Esto creará un archivo zip en la raíz de D:named test.zipque contendrá un solo archivo llamado mytext.txt. Por supuesto, puede agregar más entradas zip y también especificar un subdirectorio como este:
ZipEntry e =newZipEntry("folderName/mytext.txt");
Puede encontrar más información sobre la compresión con Java aquí .
¿Por qué se incluyen las dos líneas byte[] data = sb.toString().getBytes(); out.write(data, 0, data.length);en este ejemplo de código? ¿Cuál es su propósito?
Kaadzia
@kdzia, la primera línea convierte el valor de StringBuilder en una matriz de bytes, y la segunda línea toma esa matriz de bytes y la escribe en ZipEntry dentro del archivo "test.zip". Estas líneas son necesarias porque los archivos Zip funcionan con conjuntos de bytes, no con cadenas.
OrangeWombat
3
Pero ... en el ejemplo anterior, ¿cómo tiene el StringBuilder algo más que "Test String"? Estoy un poco confundido por esto también. Si está escribiendo el sb.toString().getBytes()archivo ZIP, ¿espero que desee que contenga los bytes del archivo que está comprimiendo? ¿O me estoy perdiendo algo?
RobA
3
@RobA no te estás perdiendo nada. El StringBuilder está destinado a contener el texto que el OP obtuvo de su base de datos. OP simplemente tendría que reemplazar "prueba de la cuerda" (incluyendo las comillas) para algo así como getTextFromDatabase ()
Blueriver
Gracias, @Blueriver
RobA
143
Java 7 tiene ZipFileSystem integrado, que puede usarse para crear, escribir y leer archivos desde archivos zip.
Map<String,String> env =newHashMap<>();// Create the zip file if it doesn't exist
env.put("create","true");
URI uri = URI.create("jar:file:/codeSamples/zipfs/zipfstest.zip");try(FileSystem zipfs =FileSystems.newFileSystem(uri, env)){Path externalTxtFile =Paths.get("/codeSamples/zipfs/SomeTextFile.txt");Path pathInZipfile = zipfs.getPath("/SomeTextFile.txt");// Copy a file into the zip fileFiles.copy(externalTxtFile, pathInZipfile,StandardCopyOption.REPLACE_EXISTING);}
¿Hay alguna manera de hacer que esto funcione si la extensión no lo es .zip? Necesito escribir un .fooarchivo, que está formateado exactamente como un archivo zip, pero con una extensión diferente. Sé que podría hacer un .ziparchivo y renombrarlo, pero crearlo con el nombre correcto sería más simple.
Troy Daniels
2
@TroyDaniels, el ejemplo anterior también funciona con una extensión diferente, ya que utiliza el jar:file:prefijo para crear URI.
Sivabalan
10
El único problema que puede aparecer aquí es que no funcionará en caso de que tenga directorios. Entonces, por ejemplo, si tiene "/dir/SomeTextFile.txt" en la pathInZipfilevariable, debe crear el 'dir' dentro del archivo .zip. Para esto, solo agregue la siguiente línea: Files.createDirectories(pathInZipfile.getParent())antes de invocar el Files.copymétodo.
D. Naumovich
¿Cómo establecer el nivel de compresión?
cdalxndr
34
Para escribir un archivo ZIP, utiliza un ZipOutputStream. Para cada entrada que desee colocar en el archivo ZIP, cree un objeto ZipEntry. Pasa el nombre del archivo al constructor ZipEntry; establece los otros parámetros, como la fecha del archivo y el método de descompresión. Puede anular esta configuración si lo desea. Luego, llama al método putNextEntry de ZipOutputStream para comenzar a escribir un nuevo archivo. Envíe los datos del archivo a la secuencia ZIP. Cuando haya terminado, llame a closeEntry. Repita para todos los archivos que desea almacenar. Aquí hay un esqueleto de código:
FileOutputStream fout =newFileOutputStream("test.zip");ZipOutputStream zout =newZipOutputStream(fout);for all files
{ZipEntry ze =newZipEntry(filename);
zout.putNextEntry(ze);
send data to zout;
zout.closeEntry();}
zout.close();
Aquí hay un código de ejemplo para comprimir un directorio completo (incluidos los subarchivos y subdirectorios), está utilizando la función de árbol de archivos de caminata de Java NIO.
Tiene que crear principalmente dos funciones. Primero es writeToZipFile () y segundo es createZipfileForOutPut .... y luego llama a createZipfileForOutPut ('nombre de archivo de .zip') `...
publicstaticvoid writeToZipFile(String path,ZipOutputStream zipStream)throwsFileNotFoundException,IOException{System.out.println("Writing file : '"+ path +"' to zip file");File aFile =newFile(path);FileInputStream fis =newFileInputStream(aFile);ZipEntry zipEntry =newZipEntry(path);
zipStream.putNextEntry(zipEntry);byte[] bytes =newbyte[1024];int length;while((length = fis.read(bytes))>=0){
zipStream.write(bytes,0, length);}
zipStream.closeEntry();
fis.close();}publicstaticvoid createZipfileForOutPut(String filename){String home =System.getProperty("user.home");// File directory = new File(home + "/Documents/" + "AutomationReport");File directory =newFile("AutomationReport");if(!directory.exists()){
directory.mkdir();}try{FileOutputStream fos =newFileOutputStream("Path to your destination"+ filename +".zip");ZipOutputStream zos =newZipOutputStream(fos);
writeToZipFile("Path to file which you want to compress / zip", zos);
zos.close();
fos.close();}catch(FileNotFoundException e){
e.printStackTrace();}catch(IOException e){
e.printStackTrace();}}
Como me tomó un tiempo resolverlo, pensé que sería útil publicar mi solución usando Java 7+ ZipFileSystem
openZip(runFile);
addToZip(filepath);//loop construct;
zipfs.close();privatevoid openZip(File runFile)throwsIOException{Map<String,String> env =newHashMap<>();
env.put("create","true");
env.put("encoding","UTF-8");Files.deleteIfExists(runFile.toPath());
zipfs =FileSystems.newFileSystem(URI.create("jar:"+ runFile.toURI().toString()), env);}privatevoid addToZip(String filename)throwsIOException{Path externalTxtFile =Paths.get(filename).toAbsolutePath();Path pathInZipfile = zipfs.getPath(filename.substring(filename.lastIndexOf("results")));//all files to be stored have a common base folder, results/ in my caseif(Files.isDirectory(externalTxtFile)){Files.createDirectories(pathInZipfile);try(DirectoryStream<Path> ds =Files.newDirectoryStream(externalTxtFile)){for(Path child : ds){
addToZip(child.normalize().toString());//recursive call}}}else{// copy file to zip fileFiles.copy(externalTxtFile, pathInZipfile,StandardCopyOption.REPLACE_EXISTING);}}
Dado exportPathy queryResultscomo variables de cadena, el siguiente bloque crea un results.ziparchivo debajo exportPathy escribe el contenido queryResultsen un results.txtarchivo dentro del zip.
URI uri = URI.create("jar:file:"+ exportPath +"/results.zip");Map<String,String> env =Collections.singletonMap("create","true");try(FileSystem zipfs =FileSystems.newFileSystem(uri, env)){Path filePath = zipfs.getPath("/results.txt");byte[] fileContent = queryResults.getBytes();Files.write(filePath, fileContent,StandardOpenOption.CREATE);}
Crear un archivo zip con un solo archivo / Agregar un solo archivo a un zip existente
new ZipFile("filename.zip").addFile("filename.ext");
O
new ZipFile("filename.zip").addFile(new File("filename.ext"));
Crear un archivo zip con múltiples archivos / Agregar múltiples archivos a un zip existente
new ZipFile("filename.zip").addFiles(Arrays.asList(new File("first_file"), new File("second_file")));
Crear un archivo zip al agregarle una carpeta / Agregar una carpeta a un zip existente
new ZipFile("filename.zip").addFolder(new File("/user/myuser/folder_to_add"));
Crear un archivo zip desde una secuencia / Agregar una secuencia a un zip existente
new ZipFile("filename.zip").addStream(inputStream, new ZipParameters());
byte[] data = sb.toString().getBytes(); out.write(data, 0, data.length);
en este ejemplo de código? ¿Cuál es su propósito?sb.toString().getBytes()
archivo ZIP, ¿espero que desee que contenga los bytes del archivo que está comprimiendo? ¿O me estoy perdiendo algo?Java 7 tiene ZipFileSystem integrado, que puede usarse para crear, escribir y leer archivos desde archivos zip.
Java Doc: proveedor de ZipFileSystem
fuente
.zip
? Necesito escribir un.foo
archivo, que está formateado exactamente como un archivo zip, pero con una extensión diferente. Sé que podría hacer un.zip
archivo y renombrarlo, pero crearlo con el nombre correcto sería más simple.jar:file:
prefijo para crear URI.pathInZipfile
variable, debe crear el 'dir' dentro del archivo .zip. Para esto, solo agregue la siguiente línea:Files.createDirectories(pathInZipfile.getParent())
antes de invocar elFiles.copy
método.Para escribir un archivo ZIP, utiliza un ZipOutputStream. Para cada entrada que desee colocar en el archivo ZIP, cree un objeto ZipEntry. Pasa el nombre del archivo al constructor ZipEntry; establece los otros parámetros, como la fecha del archivo y el método de descompresión. Puede anular esta configuración si lo desea. Luego, llama al método putNextEntry de ZipOutputStream para comenzar a escribir un nuevo archivo. Envíe los datos del archivo a la secuencia ZIP. Cuando haya terminado, llame a closeEntry. Repita para todos los archivos que desea almacenar. Aquí hay un esqueleto de código:
fuente
Aquí hay un código de ejemplo para comprimir un directorio completo (incluidos los subarchivos y subdirectorios), está utilizando la función de árbol de archivos de caminata de Java NIO.
Para usar esto, solo llame
y obtendrá un directorio de archivo zip ToCompress.zip
fuente
Controlador de arranque de Spring, comprime los archivos en un directorio y se puede descargar.
fuente
fuente
Así es como se crea un archivo zip desde un archivo fuente:
fuente
Fila india:
Archivos múltiples:
fuente
Tiene que crear principalmente dos funciones. Primero es writeToZipFile () y segundo es createZipfileForOutPut .... y luego llama a createZipfileForOutPut ('nombre de archivo de .zip') `...
fuente
Si quieres descomprimir sin software mejor usa este código. Otro código con archivos pdf envía un error al descomprimir manualmente
fuente
Como me tomó un tiempo resolverlo, pensé que sería útil publicar mi solución usando Java 7+ ZipFileSystem
fuente
fuente
Dado
exportPath
yqueryResults
como variables de cadena, el siguiente bloque crea unresults.zip
archivo debajoexportPath
y escribe el contenidoqueryResults
en unresults.txt
archivo dentro del zip.fuente
Usando Jeka https://jeka.dev JkPathTree, es bastante sencillo.
fuente
Hay otra opción al usar
zip4j
en https://github.com/srikanth-lingala/zip4jCrear un archivo zip con un solo archivo / Agregar un solo archivo a un zip existente
new ZipFile("filename.zip").addFile("filename.ext");
Onew ZipFile("filename.zip").addFile(new File("filename.ext"));
Crear un archivo zip con múltiples archivos / Agregar múltiples archivos a un zip existente
new ZipFile("filename.zip").addFiles(Arrays.asList(new File("first_file"), new File("second_file")));
Crear un archivo zip al agregarle una carpeta / Agregar una carpeta a un zip existente
new ZipFile("filename.zip").addFolder(new File("/user/myuser/folder_to_add"));
Crear un archivo zip desde una secuencia / Agregar una secuencia a un zip existente
new ZipFile("filename.zip").addStream(inputStream, new ZipParameters());
fuente