una - comprimir varios archivos en un zip con java
Cómo crear un archivo zip en Java (10)
Tengo un archivo de texto dinámico que selecciona 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?
Aquí hay un código de ejemplo para comprimir un directorio completo (incluidos subarchivos y subdirectorios), está utilizando la función de árbol de archivos walk de Java NIO.
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
public class ZipCompress {
public static void compress(String dirPath) {
Path sourceDir = Paths.get(dirPath);
String zipFileName = dirPath.concat(".zip");
try {
ZipOutputStream outputStream = new ZipOutputStream(new FileOutputStream(zipFileName));
Files.walkFileTree(sourceDir, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attributes) {
try {
Path targetFile = sourceDir.relativize(file);
outputStream.putNextEntry(new ZipEntry(targetFile.toString()));
byte[] bytes = Files.readAllBytes(file);
outputStream.write(bytes, 0, bytes.length);
outputStream.closeEntry();
} catch (IOException e) {
e.printStackTrace();
}
return FileVisitResult.CONTINUE;
}
});
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Para usar esto, solo llame
ZipCompress.compress("target/directoryToCompress");
y obtendrá un archivo zip directoryToCompress.zip
Como me tomó un tiempo darme cuenta, pensé que sería útil publicar mi solución usando Java 7+ ZipFileSystem
openZip(runFile);
addToZip(filepath); //loop construct;
zipfs.close();
private void openZip(File runFile) throws IOException {
Map<String, String> env = new HashMap<>();
env.put("create", "true");
env.put("encoding", "UTF-8");
Files.deleteIfExists(runFile.toPath());
zipfs = FileSystems.newFileSystem(URI.create("jar:" + runFile.toURI().toString()), env);
}
private void addToZip(String filename) throws IOException {
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 case
if (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 file
Files.copy(externalTxtFile, pathInZipfile, StandardCopyOption.REPLACE_EXISTING);
}
}
Controlador de inicio de primavera, comprima los archivos en un directorio y puede descargarse.
@RequestMapping(value = "/files.zip")
@ResponseBody
byte[] filesZip() throws IOException {
File dir = new File("./");
File[] filesArray = dir.listFiles();
if (filesArray == null || filesArray.length == 0)
System.out.println(dir.getAbsolutePath() + " have no file!");
ByteArrayOutputStream bo = new ByteArrayOutputStream();
ZipOutputStream zipOut= new ZipOutputStream(bo);
for(File xlsFile:filesArray){
if(!xlsFile.isFile())continue;
ZipEntry zipEntry = new ZipEntry(xlsFile.getName());
zipOut.putNextEntry(zipEntry);
zipOut.write(IOUtils.toByteArray(new FileInputStream(xlsFile)));
zipOut.closeEntry();
}
zipOut.close();
return bo.toByteArray();
}
El siguiente enlace podría ayudar:
Java 7 tiene ZipFileSystem integrado, que se puede usar para crear, escribir y leer archivos desde un archivo zip.
Java Doc: proveedor de ZipFileSystem
Map<String, String> env = new HashMap<>();
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 file
Files.copy(externalTxtFile, pathInZipfile, StandardCopyOption.REPLACE_EXISTING);
}
Mira este ejemplo:
StringBuilder sb = new StringBuilder();
sb.append("Test String");
File f = new File("d://test.zip");
ZipOutputStream out = new ZipOutputStream(new FileOutputStream(f));
ZipEntry e = new ZipEntry("mytext.txt");
out.putNextEntry(e);
byte[] data = sb.toString().getBytes();
out.write(data, 0, data.length);
out.closeEntry();
out.close();
Esto creará un Zip-File ubicado en la raíz de D: llamado ''test.zip'' que contendrá un solo archivo llamado ''mytext.txt''. Por supuesto, puede agregar más entradas zip y también especificar un subdirectorio como:
ZipEntry e = new ZipEntry("folderName/mytext.txt");
Puede encontrar más información sobre la compresión con java aquí:
http://www.oracle.com/technetwork/articles/java/compress-1565076.html
Para escribir un archivo ZIP, usa un ZipOutputStream. Para cada entrada que desee colocar en el archivo ZIP, crea un objeto ZipEntry. Usted 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 termine, llame a closeEntry. Repita para todos los archivos que desea almacenar. Aquí hay un esqueleto de código:
FileOutputStream fout = new FileOutputStream("test.zip");
ZipOutputStream zout = new ZipOutputStream(fout);
for all files
{
ZipEntry ze = new ZipEntry(filename);
zout.putNextEntry(ze);
send data to zout;
zout.closeEntry();
}
zout.close();
Si desea descomprimir sin software, mejor use este código. Otro código con archivos pdf envía error en la descompresión manual
byte[] buffer = new byte[1024];
try
{
FileOutputStream fos = new FileOutputStream("123.zip");
ZipOutputStream zos = new ZipOutputStream(fos);
ZipEntry ze= new ZipEntry("file.pdf");
zos.putNextEntry(ze);
FileInputStream in = new FileInputStream("file.pdf");
int len;
while ((len = in.read(buffer)) > 0)
{
zos.write(buffer, 0, len);
}
in.close();
zos.closeEntry();
zos.close();
}
catch(IOException ex)
{
ex.printStackTrace();
}
Zip4j usa código completamente Java sin ningún soporte de código nativo, y eso es lo que lo hace más adecuado para mí. Zip4j ofrece las siguientes características:
- Crear, Agregar, Extraer, Actualizar, Eliminar archivos de un archivo Zip
- Leer / Escribir archivos Zip protegidos con contraseña
- Admite el cifrado AES 128/256
- Admite cifrado Zip estándar
- Admite formato Zip64
- Compatible con Store (sin compresión) y desinflar el método de compresión
- Crear o extraer archivos de archivos Zip divididos (por ejemplo: z01, z02, ... zip)
- Admite nombres de archivos Unicode
- Monitor de progreso
CreatePasswordProtectedZipExample.java
import java.io.File;
import java.util.ArrayList;
import net.lingala.zip4j.core.ZipFile;
import net.lingala.zip4j.exception.ZipException;
import net.lingala.zip4j.model.ZipParameters;
import net.lingala.zip4j.util.Zip4jConstants;
public class CreatePasswordProtectedZipExample
{
public static void main(String[] args)
{
try {
//This is name and path of zip file to be created
ZipFile zipFile = new ZipFile("C:/temp/test.zip");
//Add files to be archived into zip file
ArrayList<File> filesToAdd = new ArrayList<File>();
filesToAdd.add(new File("C:/temp/test1.txt"));
filesToAdd.add(new File("C:/temp/test2.txt"));
//Initiate Zip Parameters which define various properties
ZipParameters parameters = new ZipParameters();
parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE); // set compression method to deflate compression
//DEFLATE_LEVEL_FASTEST - Lowest compression level but higher speed of compression
//DEFLATE_LEVEL_FAST - Low compression level but higher speed of compression
//DEFLATE_LEVEL_NORMAL - Optimal balance between compression level/speed
//DEFLATE_LEVEL_MAXIMUM - High compression level with a compromise of speed
//DEFLATE_LEVEL_ULTRA - Highest compression level but low speed
parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL);
//Set the encryption flag to true
parameters.setEncryptFiles(true);
//Set the encryption method to AES Zip Encryption
parameters.setEncryptionMethod(Zip4jConstants.ENC_METHOD_AES);
//AES_STRENGTH_128 - For both encryption and decryption
//AES_STRENGTH_192 - For decryption only
//AES_STRENGTH_256 - For both encryption and decryption
//Key strength 192 cannot be used for encryption. But if a zip file already has a
//file encrypted with key strength of 192, then Zip4j can decrypt this file
parameters.setAesKeyStrength(Zip4jConstants.AES_STRENGTH_256);
//Set password
parameters.setPassword("howtodoinjava");
//Now add files to the zip file
zipFile.addFiles(filesToAdd, parameters);
}
catch (ZipException e)
{
e.printStackTrace();
}
}
}
public static void main(String args[])
{
omtZip("res/", "omt.zip");
}
public static void omtZip(String path,String outputFile)
{
final int BUFFER = 2048;
boolean isEntry = false;
ArrayList<String> directoryList = new ArrayList<String>();
File f = new File(path);
if(f.exists())
{
try {
FileOutputStream fos = new FileOutputStream(outputFile);
ZipOutputStream zos = new ZipOutputStream(new BufferedOutputStream(fos));
byte data[] = new byte[BUFFER];
if(f.isDirectory())
{
//This is Directory
do{
String directoryName = "";
if(directoryList.size() > 0)
{
directoryName = directoryList.get(0);
System.out.println("Directory Name At 0 :"+directoryName);
}
String fullPath = path+directoryName;
File fileList = null;
if(directoryList.size() == 0)
{
//Main path (Root Directory)
fileList = f;
}else
{
//Child Directory
fileList = new File(fullPath);
}
String[] filesName = fileList.list();
int totalFiles = filesName.length;
for(int i = 0 ; i < totalFiles ; i++)
{
String name = filesName[i];
File filesOrDir = new File(fullPath+name);
if(filesOrDir.isDirectory())
{
System.out.println("New Directory Entry :"+directoryName+name+"/");
ZipEntry entry = new ZipEntry(directoryName+name+"/");
zos.putNextEntry(entry);
isEntry = true;
directoryList.add(directoryName+name+"/");
}else
{
System.out.println("New File Entry :"+directoryName+name);
ZipEntry entry = new ZipEntry(directoryName+name);
zos.putNextEntry(entry);
isEntry = true;
FileInputStream fileInputStream = new FileInputStream(filesOrDir);
BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream, BUFFER);
int size = -1;
while( (size = bufferedInputStream.read(data, 0, BUFFER)) != -1 )
{
zos.write(data, 0, size);
}
bufferedInputStream.close();
}
}
if(directoryList.size() > 0 && directoryName.trim().length() > 0)
{
System.out.println("Directory removed :"+directoryName);
directoryList.remove(0);
}
}while(directoryList.size() > 0);
}else
{
//This is File
//Zip this file
System.out.println("Zip this file :"+f.getPath());
FileInputStream fis = new FileInputStream(f);
BufferedInputStream bis = new BufferedInputStream(fis,BUFFER);
ZipEntry entry = new ZipEntry(f.getName());
zos.putNextEntry(entry);
isEntry = true;
int size = -1 ;
while(( size = bis.read(data,0,BUFFER)) != -1)
{
zos.write(data, 0, size);
}
}
//CHECK IS THERE ANY ENTRY IN ZIP ? ----START
if(isEntry)
{
zos.close();
}else
{
zos = null;
System.out.println("No Entry Found in Zip");
}
//CHECK IS THERE ANY ENTRY IN ZIP ? ----START
}catch(Exception e)
{
e.printStackTrace();
}
}else
{
System.out.println("File or Directory not found");
}
}
}