【问题标题】:Groovy - how to zip a whole directory in Groovy?Groovy - 如何在 Groovy 中压缩整个目录?
【发布时间】:2019-06-06 12:54:35
【问题描述】:

我找到了an example on how to zip all the files in a folder,但我想压缩整个文件夹及其所有子文件夹以及所有子文件夹中包含的文件。

我正在使用 groovy,所以 Java 解决方案非常好。

如何在 groovy 中压缩整个文件夹及其内容?

【问题讨论】:

标签: java groovy directory zip


【解决方案1】:

您可以为此使用Zeroturnaround Zip

ZipUtil.pack(new File("/your/folder/here"), new File("/your/zip/here.zip"));

添加此依赖项

<dependency>
  <groupId>org.zeroturnaround</groupId>
  <artifactId>zt-zip</artifactId>
  <version>1.13</version>
  <type>jar</type>
</dependency>

[更新]

这是使用 Java 8 解决方案的一种方式:

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 AppZip {

    private List<String> fileList;
    private String sourceFolder;

    AppZip(String sourceFolder) {
        this.sourceFolder = sourceFolder;
        fileList = new ArrayList<>();
    }

    /**
     * Zip it
     *
     * @param zipFile output ZIP file location
     */
    public void zipIt(String zipFile) {

        byte[] buffer = new byte[1024];

        try {
            generateFileList(new File(sourceFolder));

            FileOutputStream fos = new FileOutputStream(zipFile);
            ZipOutputStream zos = new ZipOutputStream(fos);

            for (String file : this.fileList) {

                ZipEntry ze = new ZipEntry(file);
                zos.putNextEntry(ze);

                FileInputStream fin =
                        new FileInputStream(sourceFolder + File.separator + file);

                int len;
                while ((len = fin.read(buffer)) > 0) {
                    zos.write(buffer, 0, len);
                }

                fin.close();
            }

            zos.closeEntry();
            zos.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    /**
     * Traverse a directory and get all files,
     * and add the file into fileList
     *
     * @param node file or directory
     */
    public void generateFileList(File node) {

        //add file only
        if (node.isFile()) {
            fileList.add(generateZipEntry(node.getAbsoluteFile().toString()));
        }

        if (node.isDirectory()) {
            String[] subNote = node.list();
            for (String filename : subNote) {
                generateFileList(new File(node, filename));
            }
        }

    }

    /**
     * Format the file path for zip
     *
     * @param file file path
     * @return Formatted file path
     */
    private String generateZipEntry(String file) {
        return file.substring(sourceFolder.length() + 1);
    }
}

然后调用:

        AppZip appZip = new AppZip("/your/folder/here");
        appZip.zipIt("/your/zip/here");

【讨论】:

  • 谢谢!由于它不是一个 Maven 项目,有什么办法可以下载一两个 jar 并使其工作?我正在运行一个简单的 groovy 脚本,我没有 Maven 项目。我尝试导入jar,运行时找不到org/slf4j/LoggerFactory类。
【解决方案2】:

根据@urichenslin 的回答,这是一个与子目录一起使用并解决@MistaWizard 评论的问题:

static File compress(final File srcDir, final File zipFile) {
    ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zipFile))
    srcDir.eachFileRecurse({
        zos.putNextEntry(new ZipEntry(it.path - srcDir.path + (it.directory ? "/" : "")))
        if(it.file) { zos << it.bytes }
        zos.closeEntry()
    })
    zos.close()
    return zipFile
}

【讨论】:

    【解决方案3】:

    这个解决方案不是更时髦一点吗?

    def zipDir(srcDir, zipFile) {
        def dir = new File(srcDir)
        def files = []
        dir.eachFileRecurse(groovy.io.FileType.FILES) { file ->
            files << file
        }
    
        FileOutputStream fos = new FileOutputStream(zipFile)
        def zos = new java.util.zip.ZipOutputStream(fos)
    
        for (file in files) {
            zos.putNextEntry(new java.util.zip.ZipEntry(file.path.minus(srcDir)))
            zos << file.bytes
            zos.closeEntry()
        }
    
        // close the ZipOutputStream
        zos.close()
    }
    

    【讨论】:

    • 是的,并且确实创建了包含该文件的 zip 文件,但是我使用了 PNG 并且损坏的 PNG 有一个完全不同的问题,因此它不是防弹的,我还没有用其他文件对其进行测试。希望我可以让它与 PNG 一起使用,因为这种方法更简单
    • @MistaWizard :问题出在这一行:zos &lt;&lt; file,因为它存储的是文件名而不是实际数据。我编辑了答案。如果您也想要子目录,请查看我的答案。
    【解决方案4】:

    这是从srcDir 压缩所有文件(包括子目录)并将结果保存为zipFile 的解决方案。

    static void compress(File srcDir, File zipFile) {
        def output = new ZipOutputStream(new FileOutputStream(zipFile))
        output.setLevel(Deflater.BEST_COMPRESSION) //Use what you need
    
        srcDir.eachFileRecurse(groovy.io.FileType.FILES) {
            def name = (it.path - srcDir).substring(1)
            output.putNextEntry(new ZipEntry(name))
            output.write(it.bytes)
            output.closeEntry()
        }
    
        output.close()
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-12-22
      • 1970-01-01
      • 1970-01-01
      • 2010-10-13
      • 1970-01-01
      • 1970-01-01
      • 2014-09-01
      • 2013-08-13
      相关资源
      最近更新 更多