首页 文章

压缩/解压缩文件的优秀Java库是什么? [关闭]

提问于
浏览
196

我查看了JDK和Apache压缩库附带的默认Zip库,我对它们不满意有三个原因:

对我来说(2)和(3)是次要的,但我真的想要一个带有单线界面的良好测试库 .

9 回答

  • 251

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


    将jar从hereadd it下载到项目构建路径 . class bellow可以压缩和提取任何文件或文件夹,无论是否有密码保护 -

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

    您可以查看的另一个选项是 zt-zip ,可从Maven中心获得,项目页面位于https://github.com/zeroturnaround/zt-zip

    它具有标准的打包和解包功能(在流和文件系统上)许多辅助方法来测试存档中的文件或添加/删除条目 .

  • 0

    有了Apache Commons-IOIOUtils,你可以这样做:

    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

  • 0

    一个非常好的项目是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();
    }
    
  • 20

    仅使用JDK提取zip文件及其所有子文件夹:

    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();
            }
        }
    }
    
  • 58

    你看过http://commons.apache.org/vfs/了吗?它声称可以为您简化很多事情 . 但我从未在项目中使用过它 .

    我也不了解除JDK或Apache Compression之外的Java-Native压缩库 .

    我记得有一次我们从Apache Ant中删除了一些功能 - 他们有很多内置的压缩/解压缩工具 .

    使用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();
    }
    
  • 26

    我知道它已经很晚了,而且有很多答案,但这个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>
    
  • 12

    另一种选择是JZlib . 根据我的经验,它比zip4J更少"file-centered",所以如果您需要处理内存中的blob而不是文件,您可能需要查看它 .

  • 7

相关问题