java directory zip folder

cómo comprimir una carpeta usando java



directory zip (11)

Supongamos que tengo la siguiente estructura de directorio.

D:/reports/january/

Dentro de enero se supone que dos archivos de Excel dicen A.xls y B.xls. Hay muchos lugares donde se ha escrito sobre cómo comprimir archivos usando java.util.zip . Pero quiero comprimir la carpeta de enero en la carpeta de informes para que ambos enero y enero.zip estén presentes en los informes. ( Eso significa que cuando descomprima el archivo january.zip debería obtener la carpeta de enero ).

¿Alguien puede darme el código para hacer esto usando java.util.zip ? Por favor, avíseme si esto se puede hacer más fácilmente utilizando otras bibliotecas.

Muchas gracias...


¿Has probado la biblioteca Zeroturnaround Zip ? ¡Es realmente bueno! Zip una carpeta es solo un trazador de líneas:

ZipUtil.pack(new File("D://reports//january//"), new File("D://reports//january.zip"));

(gracias a Oleg Šelajev por el ejemplo)


Aquí está el ejemplo de Java 8+:

public static void pack(String sourceDirPath, String zipFilePath) throws IOException { Path p = Files.createFile(Paths.get(zipFilePath)); try (ZipOutputStream zs = new ZipOutputStream(Files.newOutputStream(p))) { Path pp = Paths.get(sourceDirPath); Files.walk(pp) .filter(path -> !Files.isDirectory(path)) .forEach(path -> { ZipEntry zipEntry = new ZipEntry(pp.relativize(path).toString()); try { zs.putNextEntry(zipEntry); Files.copy(path, zs); zs.closeEntry(); } catch (IOException e) { System.err.println(e); } }); } }


Aquí hay una solución bastante tersa de Java 7+ que se basa exclusivamente en las clases vanda JDK, no se necesitan bibliotecas de terceros:

public static void pack(final Path folder, final Path zipFilePath) throws IOException { try ( FileOutputStream fos = new FileOutputStream(zipFilePath.toFile()); ZipOutputStream zos = new ZipOutputStream(fos) ) { Files.walkFileTree(folder, new SimpleFileVisitor<Path>() { public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { zos.putNextEntry(new ZipEntry(folder.relativize(file).toString())); Files.copy(file, zos); zos.closeEntry(); return FileVisitResult.CONTINUE; } public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { zos.putNextEntry(new ZipEntry(folder.relativize(dir).toString() + "/")); zos.closeEntry(); return FileVisitResult.CONTINUE; } }); } }

Copia todos los archivos en la folder , incluidos los directorios vacíos, y crea un archivo zip en zipFilePath .


Encontré que esta solución funcionó perfectamente bien para mí. No requiere ninguna API de terceros

''prueba'' es en realidad una carpeta con muchos archivos dentro.

String folderPath= "C:/Users/Desktop/test"; String zipPath = "C:/Users/Desktop/test1.zip"; private boolean zipDirectory(String folderPath, String zipPath) throws IOException{ byte[] buffer = new byte[1024]; FileInputStream fis = null; ZipOutputStream zos = null; try{ zos = new ZipOutputStream(new FileOutputStream(zipPath)); updateSourceFolder(new File(folderPath)); if (sourceFolder == null) { zos.close(); return false; } generateFileAndFolderList(new File(folderPath)); for (String unzippedFile: fileList) { System.out.println(sourceFolder + unzippedFile); ZipEntry entry = new ZipEntry(unzippedFile); zos.putNextEntry(entry); if ((unzippedFile.substring(unzippedFile.length()-1)).equals(File.separator)) continue; try{ fis = new FileInputStream(sourceFolder + unzippedFile); int len=0; while ((len = fis.read(buffer))>0) { zos.write(buffer,0,len); } } catch(IOException e) { return false; } finally { if (fis != null) fis.close(); } } zos.closeEntry(); } catch(IOException e) { return false; } finally { zos.close(); fileList = null; sourceFolder = null; } return true; } private void generateFileAndFolderList(File node) { if (node.isFile()) { fileList.add(generateZipEntry(node.getAbsoluteFile().toString())); } if (node.isDirectory()) { String dir = node.getAbsoluteFile().toString(); fileList.add(dir.substring(sourceFolder.length(), dir.length()) + File.separator); String[] subNode = node.list(); for (String fileOrFolderName : subNode) { generateFileAndFolderList(new File(node, fileOrFolderName)); } } } private void updateSourceFolder(File node) { if (node.isFile() || node.isDirectory()) { String sf = node.getAbsoluteFile().toString(); sourceFolder = sf.substring(0, (sf.lastIndexOf("/") > 0 ? sf.lastIndexOf("/") : sf.lastIndexOf("//"))); sourceFolder += File.separator; } else sourceFolder = null; } private String generateZipEntry(String file) { return file.substring(sourceFolder.length(), file.length()); }


Este método cierra una carpeta y agrega todos los archivos y carpetas secundarios (incluidas las carpetas vacías) en el archivo zip.

void zipFolder(Path sourceDir, Path targetFile) throws IOException { ZipDirectoryVisitor zipVisitor = new ZipDirectoryVisitor(sourceDir); Files.walkFileTree(sourceDir, zipVisitor); FileOutputStream fos = new FileOutputStream(targetFile.toString()); ZipOutputStream zos = new ZipOutputStream(fos); byte[] buffer = new byte[1024]; for (ZipEntry entry : zipVisitor.getZipEntries()) { zos.putNextEntry(entry); Path curFile = Paths.get(sourceDir.getParent().toString(), entry.toString()); if (!curFile.toFile().isDirectory()) { FileInputStream in = new FileInputStream(Paths.get(sourceDir.getParent().toString(), entry.toString()).toString()); int len; while ((len = in.read(buffer)) > 0) { zos.write(buffer, 0, len); } in.close(); } zos.closeEntry(); } zos.close(); }

Y aquí está la implementación de ZipDirectoryVisitor:

class ZipDirectoryVisitor extends SimpleFileVisitor<Path> { private Path dirToZip; private List<ZipEntry> zipEntries; // files and folders inside source folder as zip entries public ZipDirectoryVisitor(Path dirToZip) throws IOException { this.dirToZip = dirToZip; zipEntries = new ArrayList<>(); } @Override public FileVisitResult visitFile(Path path, BasicFileAttributes basicFileAttributes) throws IOException { // According to zip standard backslashes // should not be used in zip entries String zipFile = dirToZip.getParent().relativize(path).toString().replace("//", "/"); ZipEntry entry = new ZipEntry(zipFile); zipEntries.add(entry); return FileVisitResult.CONTINUE; } @Override public FileVisitResult preVisitDirectory(Path path, BasicFileAttributes basicFileAttributes) throws IOException { String zipDir = dirToZip.getParent().relativize(path).toString().replace("//", "/"); // Zip directory entries should end with a forward slash ZipEntry entry = new ZipEntry(zipDir + "/"); zipEntries.add(entry); return FileVisitResult.CONTINUE; } @Override public FileVisitResult visitFileFailed(Path path, IOException e) throws IOException { System.err.format("Could not visit file %s while creating a file list from file tree", path); return FileVisitResult.TERMINATE; } public List<ZipEntry> getZipEntries() { return zipEntries; } }


Java 6 +

import java.io.*; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; public class Zip { private static final FileFilter FOLDER_FILTER = new FileFilter() { @Override public boolean accept(File pathname) { return pathname.isDirectory(); } }; private static final FileFilter FILE_FILTER = new FileFilter() { @Override public boolean accept(File pathname) { return pathname.isFile(); } }; private static void compress(File file, ZipOutputStream outputStream, String path) throws IOException { if (file.isDirectory()) { File[] subFiles = file.listFiles(FILE_FILTER); if (subFiles != null) { for (File subFile : subFiles) { compress(subFile, outputStream, new File(path, subFile.getName()).getAbsolutePath()); } } File[] subDirs = file.listFiles(FOLDER_FILTER); if (subDirs != null) { for (File subDir : subDirs) { compress(subDir, outputStream, new File(path, subDir.getName()).getAbsolutePath()); } } } else if (file.exists()) { outputStream.putNextEntry(new ZipEntry(path)); FileInputStream inputStream = new FileInputStream(file); byte[] buffer = new byte[1024]; int len; while ((len = inputStream.read(buffer)) >= 0) { outputStream.write(buffer, 0, len); } outputStream.closeEntry(); } } public static void compress(String dirPath, String zipFilePath) throws IOException { File file = new File(dirPath); final ZipOutputStream outputStream = new ZipOutputStream(new FileOutputStream(zipFilePath)); compress(file, outputStream, "/"); outputStream.close(); } }


Java 7+, commons.io

public final class ZipUtils { public static void zipFolder(final File folder, final File zipFile) throws IOException { zipFolder(folder, new FileOutputStream(zipFile)); } public static void zipFolder(final File folder, final OutputStream outputStream) throws IOException { try (ZipOutputStream zipOutputStream = new ZipOutputStream(outputStream)) { processFolder(folder, zipOutputStream, folder.getPath().length() + 1); } } private static void processFolder(final File folder, final ZipOutputStream zipOutputStream, final int prefixLength) throws IOException { for (final File file : folder.listFiles()) { if (file.isFile()) { final ZipEntry zipEntry = new ZipEntry(file.getPath().substring(prefixLength)); zipOutputStream.putNextEntry(zipEntry); try (FileInputStream inputStream = new FileInputStream(file)) { IOUtils.copy(inputStream, zipOutputStream); } zipOutputStream.closeEntry(); } else if (file.isDirectory()) { processFolder(file, zipOutputStream, prefixLength); } } } }


Prueba esto:

import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; public class Zip { public static void main(String[] a) throws Exception { zipFolder("D://reports//january", "D://reports//january.zip"); } static public void zipFolder(String srcFolder, String destZipFile) throws Exception { ZipOutputStream zip = null; FileOutputStream fileWriter = null; fileWriter = new FileOutputStream(destZipFile); zip = new ZipOutputStream(fileWriter); addFolderToZip("", srcFolder, zip); zip.flush(); zip.close(); } static private void addFileToZip(String path, String srcFile, ZipOutputStream zip) throws Exception { File folder = new File(srcFile); if (folder.isDirectory()) { addFolderToZip(path, srcFile, zip); } else { byte[] buf = new byte[1024]; int len; FileInputStream in = new FileInputStream(srcFile); zip.putNextEntry(new ZipEntry(path + "/" + folder.getName())); while ((len = in.read(buf)) > 0) { zip.write(buf, 0, len); } } } static private void addFolderToZip(String path, String srcFolder, ZipOutputStream zip) throws Exception { File folder = new File(srcFolder); for (String fileName : folder.list()) { if (path.equals("")) { addFileToZip(folder.getName(), srcFolder + "/" + fileName, zip); } else { addFileToZip(path + "/" + folder.getName(), srcFolder + "/" + fileName, zip); } } } }


Se puede resolver fácilmente mediante el paquete java.util.Zip sin necesidad de archivos Jar adicionales

Simplemente copie el siguiente código y run it con su IDE

//Import all needed packages package general; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; public class ZipUtils { private List <String> fileList; private static final String OUTPUT_ZIP_FILE = "Folder.zip"; private static final String SOURCE_FOLDER = "D://Reports"; // SourceFolder path public ZipUtils() { fileList = new ArrayList < String > (); } public static void main(String[] args) { ZipUtils appZip = new ZipUtils(); appZip.generateFileList(new File(SOURCE_FOLDER)); appZip.zipIt(OUTPUT_ZIP_FILE); } public void zipIt(String zipFile) { byte[] buffer = new byte[1024]; String source = new File(SOURCE_FOLDER).getName(); FileOutputStream fos = null; ZipOutputStream zos = null; try { fos = new FileOutputStream(zipFile); zos = new ZipOutputStream(fos); System.out.println("Output to Zip : " + zipFile); FileInputStream in = null; for (String file: this.fileList) { System.out.println("File Added : " + file); ZipEntry ze = new ZipEntry(source + File.separator + file); zos.putNextEntry(ze); try { in = new FileInputStream(SOURCE_FOLDER + File.separator + file); int len; while ((len = in .read(buffer)) > 0) { zos.write(buffer, 0, len); } } finally { in.close(); } } zos.closeEntry(); System.out.println("Folder successfully compressed"); } catch (IOException ex) { ex.printStackTrace(); } finally { try { zos.close(); } catch (IOException e) { e.printStackTrace(); } } } public void generateFileList(File node) { // add file only if (node.isFile()) { fileList.add(generateZipEntry(node.toString())); } if (node.isDirectory()) { String[] subNote = node.list(); for (String filename: subNote) { generateFileList(new File(node, filename)); } } } private String generateZipEntry(String file) { return file.substring(SOURCE_FOLDER.length() + 1, file.length()); } }

Consulte mkyong ..i cambió el código para el requisito de la pregunta actual


Usualmente uso una clase auxiliar que una vez escribí para esta tarea:

import java.util.zip.*; import java.io.*; public class ZipExample { public static void main(String[] args){ ZipHelper zippy = new ZipHelper(); try { zippy.zipDir("folderName","test.zip"); } catch(IOException e2) { System.err.println(e2); } } } class ZipHelper { public void zipDir(String dirName, String nameZipFile) throws IOException { ZipOutputStream zip = null; FileOutputStream fW = null; fW = new FileOutputStream(nameZipFile); zip = new ZipOutputStream(fW); addFolderToZip("", dirName, zip); zip.close(); fW.close(); } private void addFolderToZip(String path, String srcFolder, ZipOutputStream zip) throws IOException { File folder = new File(srcFolder); if (folder.list().length == 0) { addFileToZip(path , srcFolder, zip, true); } else { for (String fileName : folder.list()) { if (path.equals("")) { addFileToZip(folder.getName(), srcFolder + "/" + fileName, zip, false); } else { addFileToZip(path + "/" + folder.getName(), srcFolder + "/" + fileName, zip, false); } } } } private void addFileToZip(String path, String srcFile, ZipOutputStream zip, boolean flag) throws IOException { File folder = new File(srcFile); if (flag) { zip.putNextEntry(new ZipEntry(path + "/" +folder.getName() + "/")); } else { if (folder.isDirectory()) { addFolderToZip(path, srcFile, zip); } else { byte[] buf = new byte[1024]; int len; FileInputStream in = new FileInputStream(srcFile); zip.putNextEntry(new ZipEntry(path + "/" + folder.getName())); while ((len = in.read(buf)) > 0) { zip.write(buf, 0, len); } } } } }


Utilizaría Apache Ant , que tiene una API para llamar a las tareas desde el código de Java en lugar de desde un archivo de construcción XML.

Project p = new Project(); p.init(); Zip zip = new Zip(); zip.setProject(p); zip.setDestFile(zipFile); // a java.io.File for the zip you want to create zip.setBasedir(new File("D://reports")); zip.setIncludes("january/**"); zip.perform();

Aquí le digo que comience desde el directorio base D:/reports y comprima la carpeta de january y todo lo que contiene. Las rutas en el archivo zip resultante serán las mismas que las rutas originales relativas a D:/reports , por lo que incluirán el prefijo de january .