Что такое хорошая библиотека Java для zip / unzip файлов? [закрытый]
Я посмотрел на библиотеку Zip по умолчанию, которая поставляется с библиотеками сжатия JDK и Apache, и я недоволен ими по 3 причинам:
они раздуты и имеют плохой дизайн API. Я должен напишите 50 строк вывода байтового массива boiler plate, zip-вход, потоки файлов и закройте соответствующие потоки и поймайте исключения и переместите байтовые буферы самостоятельно? Почему я не могу иметь простой API, который выглядит так
Zipper.unzip(InputStream zipFile, File targetDirectory, String password = null)иZipper.zip(File targetDirectory, String password = null)что просто работает?Кажется, что сжатие распаковки уничтожает метаданные файла, а обработка паролей нарушена.
кроме того, все библиотеки, которые я пробовал, были 2-3x медленными по сравнению с инструментами командной строки zip, которые я получаю с UNIX?
для меня (2) и (3) являются незначительными моментами, но я действительно хочу хорошую проверенную библиотеку с однострочным интерфейсом.
9 ответов:
Я знаю его поздно, и есть много ответов, но этот zip4j является одним из лучших библиотек для молнии я использовал. Свой простой (отсутствие кода боилера) и может легко отрегулировать защищенные паролем файлы.
import net.lingala.zip4j.exception.ZipException; import net.lingala.zip4j.core.ZipFile; public static void unzip(){ String source = "some/compressed/file.zip"; String destination = "some/destination/folder"; String password = "password"; try { ZipFile zipFile = new ZipFile(source); if (zipFile.isEncrypted()) { zipFile.setPassword(password); } zipFile.extractAll(destination); } catch (ZipException e) { e.printStackTrace(); } }зависимость Maven:
<dependency> <groupId>net.lingala.zip4j</groupId> <artifactId>zip4j</artifactId> <version>1.3.2</version> </dependency>
С Apache Commons-IO ' s
IOUtilsможно сделать так:java.util.zip.ZipFile zipFile = new ZipFile(file); try { Enumeration<? extends ZipEntry> entries = zipFile.entries(); while (entries.hasMoreElements()) { ZipEntry entry = entries.nextElement(); File entryDestination = new File(outputDir, entry.getName()); if (entry.isDirectory()) { entryDestination.mkdirs(); } else { entryDestination.getParentFile().mkdirs(); InputStream in = zipFile.getInputStream(entry); OutputStream out = new FileOutputStream(entryDestination); IOUtils.copy(in, out); IOUtils.closeQuietly(in); out.close(); } } } finally { zipFile.close(); }Это все еще какой-то шаблонный код, но он имеет только 1 не экзотическую зависимость:Commons-IO
извлеките zip-файл и все его подпапки, используя только JDK:
private void extractFolder(String zipFile,String extractFolder) { try { int BUFFER = 2048; File file = new File(zipFile); ZipFile zip = new ZipFile(file); String newPath = extractFolder; new File(newPath).mkdir(); Enumeration zipFileEntries = zip.entries(); // Process each entry while (zipFileEntries.hasMoreElements()) { // grab a zip file entry ZipEntry entry = (ZipEntry) zipFileEntries.nextElement(); String currentEntry = entry.getName(); File destFile = new File(newPath, currentEntry); //destFile = new File(newPath, destFile.getName()); File destinationParent = destFile.getParentFile(); // create the parent directory structure if needed destinationParent.mkdirs(); if (!entry.isDirectory()) { BufferedInputStream is = new BufferedInputStream(zip .getInputStream(entry)); int currentByte; // establish buffer for writing file byte data[] = new byte[BUFFER]; // write the current file to disk FileOutputStream fos = new FileOutputStream(destFile); BufferedOutputStream dest = new BufferedOutputStream(fos, BUFFER); // read and write until last byte is encountered while ((currentByte = is.read(data, 0, BUFFER)) != -1) { dest.write(data, 0, currentByte); } dest.flush(); dest.close(); is.close(); } } } catch (Exception e) { Log("ERROR: "+e.getMessage()); } }Zip файлы и все его подпапки:
private void addFolderToZip(File folder, ZipOutputStream zip, String baseName) throws IOException { File[] files = folder.listFiles(); for (File file : files) { if (file.isDirectory()) { addFolderToZip(file, zip, baseName); } else { String name = file.getAbsolutePath().substring(baseName.length()); ZipEntry zipEntry = new ZipEntry(name); zip.putNextEntry(zipEntry); IOUtils.copy(new FileInputStream(file), zip); zip.closeEntry(); } } }
еще один вариант, который вы можете проверить это zt-zip доступно на странице Maven central и project по адресу https://github.com/zeroturnaround/zt-zip
Он имеет стандартные функции упаковки и распаковки (в потоках и в файловой системе) + множество вспомогательных методов для тестирования файлов в архиве или добавления/удаления записей.
полная реализация для Zip / Unzip папки / файла с zip4j
загрузить jar с здесь и добавить к вашему проекту построить путь. Элемент
classниже можно сжать и извлечь любой файл или папку, с или без защиты паролем -import java.io.File; import net.lingala.zip4j.model.ZipParameters; import net.lingala.zip4j.util.Zip4jConstants; import net.lingala.zip4j.core.ZipFile; public class Compressor { public static void zip(String targetPath, String destinationFilePath, String password) { try { ZipParameters parameters = new ZipParameters(); parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE); parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL); if(password.length()>0){ parameters.setEncryptFiles(true); parameters.setEncryptionMethod(Zip4jConstants.ENC_METHOD_AES); parameters.setAesKeyStrength(Zip4jConstants.AES_STRENGTH_256); parameters.setPassword(password); } ZipFile zipFile = new ZipFile(destinationFilePath); File targetFile = new File(targetPath); if(targetFile.isFile()){ zipFile.addFile(targetFile, parameters); }else if(targetFile.isDirectory()){ zipFile.addFolder(targetFile, parameters); } } catch (Exception e) { e.printStackTrace(); } } public static void unzip(String targetZipFilePath, String destinationFolderPath, String password) { try { ZipFile zipFile = new ZipFile(targetZipFilePath); if (zipFile.isEncrypted()) { zipFile.setPassword(password); } zipFile.extractAll(destinationFolderPath); } catch (Exception e) { e.printStackTrace(); } } /**/ /// for test only public static void main(String[] args) { String targetPath = "target\file\or\folder\path"; String zipFilePath = "zip\file\Path"; String unzippedFolderPath = "destination\folder\path"; String password = "your_password"; // keep it EMPTY<""> for applying no password protection Compressor.zip(targetPath, zipFilePath, password); Compressor.unzip(zipFilePath, unzippedFolderPath, password); }/**/ }
очень хороший проект TrueZip.
TrueZIP-это Java-плагин для виртуальных файловых систем (VFS), который обеспечивает прозрачный доступ к архивным файлам, как если бы они были просто каталогами
например (с сайт):
File file = new TFile("archive.tar.gz/README.TXT"); OutputStream out = new TFileOutputStream(file); try { // Write archive entry contents here. ... } finally { out.close(); }
другой вариант:JZlib. По моему опыту, он менее "ориентирован на файлы", чем zip4J, поэтому, если вам нужно работать с большими двоичными объектами в памяти, а не с файлами, вы можете взглянуть на него.
здесь есть полный пример для рекурсивной архивации и распаковки файлов: http://developer-tips.hubpages.com/hub/Zipping-and-Unzipping-Nested-Directories-in-Java-using-Apache-Commons-Compress
вы смотрели на http://commons.apache.org/vfs/ ? Он утверждает, что упростить много вещей для вас. Но я никогда не использовал его в проекте.
Я также не знаю Java-Native Compression libs, кроме сжатия JDK или Apache.
Я помню, как только мы вырвали некоторые функции из Apache Ant-у них есть много utils для сжатия / декомпрессии встроенных.
пример кода с VFS будет выглядеть так:
File zipFile = ...; File outputDir = ...; FileSystemManager fsm = VFS.getManager(); URI zip = zipFile.toURI(); FileObject packFileObject = fsm.resolveFile(packLocation.toString()); FileObject to = fsm.toFileObject(destDir); FileObject zipFS; try { zipFS = fsm.createFileSystem(packFileObject); fsm.toFileObject(outputDir).copyFrom(zipFS, new AllFileSelector()); } finally { zipFS.close(); }
Comments