什么是一个好的Java库来压缩/解压缩文件?[关闭]

cl25kdpy  于 2023-05-05  发布在  Java
关注(0)|答案(9)|浏览(138)

**已关闭。**此问题正在寻求书籍、工具、软件库等的建议。它不符合Stack Overflow guidelines。目前不接受答复。

我们不允许问题寻求书籍,工具,软件库等的建议。您可以编辑问题,以便可以用事实和引用来回答。
7年前关闭。
Improve this question
我查看了JDK和Apache压缩库附带的默认Zip库,我对它们不满意,原因有三:
1.它们臃肿,API设计糟糕。我必须write 50 lines of boiler plate byte array output, zip input, file out streams and close relevant streams and catch exceptions and move byte buffers on my own?为什么我不能有一个简单的API,看起来像这样的Zipper.unzip(InputStream zipFile, File targetDirectory, String password = null)Zipper.zip(File targetDirectory, String password = null)只是工作?
1.似乎压缩解压缩破坏文件元数据和密码处理是打破。
1.此外,我尝试的所有库与我在UNIX中获得的命令行zip工具相比都慢2- 3倍。
对我来说,(2)和(3)是次要的,但我真的想要一个好的测试库,一行接口。

2j4z5cfb

2j4z5cfb1#

我知道它的晚,有很多答案,但这个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>
nsc4cvqm

nsc4cvqm2#

在Java 8中,使用Apache Commons-IOIOUtils可以做到:

try (java.util.zip.ZipFile zipFile = new ZipFile(file)) {
  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();
        try (InputStream in = zipFile.getInputStream(entry);
             OutputStream out = new FileOutputStream(entryDestination)) {
            IOUtils.copy(in, out);
        }
    }
  }
}

它仍然是一些样板代码,但它只有一个非外来依赖:Commons-IO
在Java 11和更高版本中,可能会有更好的选择,请参阅ZhekaKozlov的评论。

x7rlezfr

x7rlezfr3#

解压缩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();
        }
    }
}
00jrzges

00jrzges4#

另一个可以查看的选项是zt-zip,可从Maven中心和项目页面https://github.com/zeroturnaround/zt-zip获得
它具有标准的打包和解包功能(在流和文件系统上)+许多帮助器方法来测试归档中的文件或添加/删除条目。

20jt8wwn

20jt8wwn5#

zip4j文件夹/文件压缩/解压缩完整实现

this dependency添加到构建管理器。或者,从hereadd it下载最新的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);
            } else {
                //neither file nor directory
            }

        } 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
    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);
    }/**/
}

更详细的用法请看这里。

aamkag61

aamkag616#

一个非常好的项目是TrueZip
TrueZIP是一个基于Java的虚拟文件系统(VFS)插件框架,它提供了对归档文件的透明访问,就像它们只是普通目录一样
例如(从website):

File file = new TFile("archive.tar.gz/README.TXT");
OutputStream out = new TFileOutputStream(file);
try {
   // Write archive entry contents here.
   ...
} finally {
   out.close();
}
js5cn81o

js5cn81o7#

另一个选项是JZlib。根据我的经验,它不像zip4J那样“以文件为中心”,所以如果您需要处理内存中的blob而不是文件,您可能想看看它。

yfjy0ee7

yfjy0ee79#

你看过http://commons.apache.org/vfs/吗?它声称为您简化了很多事情。但我从来没有在项目中使用过。
我也不知道除了JDK或Apache压缩之外的Java原生压缩库。
我记得有一次我们从ApacheAnt中删除了一些功能--它们内置了很多压缩/解压缩的实用程序。
使用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();
}

相关问题