Что такое хорошая библиотека Java для распаковки/распаковки файлов?
Я посмотрел на библиотеку Zip по умолчанию, которая поставляется с JDK и Apache сжатиями libs, и я недовольна ими по трем причинам:
-
Они раздуты и имеют плохой дизайн API. Я должен записать 50 строк вывода массива байтов котла, ввести zip-вход, вывести потоки файлов и закрыть соответствующие потоки и исключить исключения и переместить байт-буферы на свои собственные? Почему я не могу получить простой API, который выглядит как Zipper.unzip(InputStream zipFile, File targetDirectory, String password = null)
и Zipper.zip(File targetDirectory, String password = null)
, который просто работает?
-
Кажется, что при распаковке распаковываются метаданные файлов и обработка паролей.
-
Кроме того, все библиотеки, которые я пытался, были медленнее на 2-3 раза по сравнению с инструментами командной строки командной строки, которые я получал с помощью UNIX?
Для меня (2) и (3) являются второстепенными точками, но я действительно хочу хорошую тестируемую библиотеку с однострочным интерфейсом.
Ответы
Ответ 1
Я знаю его поздно, и есть много ответов, но это zip4j является одной из лучших библиотек для zipping, которые я использовал. Его простой (без кода котла) и может легко обрабатывать защищенные паролем файлы.
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>
Ответ 2
С Apache Commons-IO 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();
}
Это еще какой-то шаблонный код, но он имеет только одну неэкзотическую зависимость: Commons-IO
Ответ 3
Извлечь 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());
}
}
Почтовые файлы и все его подпапки:
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();
}
}
}
Ответ 4
Другой вариант, который вы можете проверить, - zt-zip, доступный с центральной страницы Maven и страницы проекта https://github.com/zeroturnaround/zt-zip
Он имеет стандартную функциональность упаковки и распаковки (в потоках и в файловой системе) + множество вспомогательных методов для проверки файлов в архиве или добавления/удаления записей.
Ответ 5
Полная реализация для Zip/Unzip File/Folder
Я использовал zip4j, как предполагает принятый ответ. Загрузите банку из здесь, и добавьте ее в ваш путь построения проекта. 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);
}/**/
}
Ответ 6
Очень приятный проект 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();
}
Ответ 7
Другой вариант - JZlib. По моему опыту, он меньше "с файловым центром", чем zip4J, поэтому, если вам нужно работать с блоками в памяти, а не с файлами, вы можете взглянуть на него.
Ответ 8
Вы посмотрели http://commons.apache.org/vfs/? Он утверждает, что упрощает вам многое. Но я никогда не использовал его в проекте.
Я также не знаю Java-Native 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();
}
Ответ 9
Здесь приведен полный пример для рекурсивного копирования и распаковки файлов:
http://developer-tips.hubpages.com/hub/Zipping-and-Unzipping-Nested-Directories-in-Java-using-Apache-Commons-Compress