当前位置: 首页 > 知识库问答 >
问题:

将目录压缩为tar。gz与Commons压缩

宇文梓
2023-03-14

我在使用共享资源压缩库创建目录的tar.gz时遇到了一个问题。我有一个目录结构如下。

parent/
    child/
        file1.raw
        fileN.raw

我正在使用以下代码进行压缩。它运行良好,无一例外。但是,当我尝试解压缩该 tar.gz时,我得到一个名为“子DirTo压缩”的文件。它的大小是正确的,因此文件在焦油过程中清楚地相互附加。所需的输出将是一个目录。我不知道我做错了什么。任何明智的共享资源压缩器都可以让我走上正确的道路吗?

CreateTarGZ() throws CompressorException, FileNotFoundException, ArchiveException, IOException {
            File f = new File("parent");
            File f2 = new File("parent/childDirToCompress");

            File outFile = new File(f2.getAbsolutePath() + ".tar.gz");
            if(!outFile.exists()){
                outFile.createNewFile();
            }
            FileOutputStream fos = new FileOutputStream(outFile);

            TarArchiveOutputStream taos = new TarArchiveOutputStream(new GZIPOutputStream(new BufferedOutputStream(fos)));
            taos.setBigNumberMode(TarArchiveOutputStream.BIGNUMBER_STAR); 
            taos.setLongFileMode(TarArchiveOutputStream.LONGFILE_GNU);
            addFilesToCompression(taos, f2, ".");
            taos.close();

        }

        private static void addFilesToCompression(TarArchiveOutputStream taos, File file, String dir) throws IOException{
            taos.putArchiveEntry(new TarArchiveEntry(file, dir));

            if (file.isFile()) {
                BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
                IOUtils.copy(bis, taos);
                taos.closeArchiveEntry();
                bis.close();
            }

            else if(file.isDirectory()) {
                taos.closeArchiveEntry();
                for (File childFile : file.listFiles()) {
                    addFilesToCompression(taos, childFile, file.getName());

                }
            }
        }

共有3个答案

微生昌勋
2023-03-14

我最终做了以下工作:

public URL createTarGzip() throws IOException {
    Path inputDirectoryPath = ...
    File outputFile = new File("/path/to/filename.tar.gz");

    try (FileOutputStream fileOutputStream = new FileOutputStream(outputFile);
            BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
            GzipCompressorOutputStream gzipOutputStream = new GzipCompressorOutputStream(bufferedOutputStream);
            TarArchiveOutputStream tarArchiveOutputStream = new TarArchiveOutputStream(gzipOutputStream)) {

        tarArchiveOutputStream.setBigNumberMode(TarArchiveOutputStream.BIGNUMBER_POSIX);
        tarArchiveOutputStream.setLongFileMode(TarArchiveOutputStream.LONGFILE_GNU);

        List<File> files = new ArrayList<>(FileUtils.listFiles(
                inputDirectoryPath,
                new RegexFileFilter("^(.*?)"),
                DirectoryFileFilter.DIRECTORY
        ));

        for (int i = 0; i < files.size(); i++) {
            File currentFile = files.get(i);

            String relativeFilePath = new File(inputDirectoryPath.toUri()).toURI().relativize(
                    new File(currentFile.getAbsolutePath()).toURI()).getPath();

            TarArchiveEntry tarEntry = new TarArchiveEntry(currentFile, relativeFilePath);
            tarEntry.setSize(currentFile.length());

            tarArchiveOutputStream.putArchiveEntry(tarEntry);
            tarArchiveOutputStream.write(IOUtils.toByteArray(new FileInputStream(currentFile)));
            tarArchiveOutputStream.closeArchiveEntry();
        }
        tarArchiveOutputStream.close();
        return outputFile.toURI().toURL();
    }
}

这解决了其他解决方案中出现的一些边缘情况。

桑鸿志
2023-03-14

我还没有弄清楚到底出了什么问题,但是搜索谷歌缓存,我发现了一个工作的例子。对不起风滚草!

public void CreateTarGZ()
    throws FileNotFoundException, IOException
{
    try {
        System.out.println(new File(".").getAbsolutePath());
        dirPath = "parent/childDirToCompress/";
        tarGzPath = "archive.tar.gz";
        fOut = new FileOutputStream(new File(tarGzPath));
        bOut = new BufferedOutputStream(fOut);
        gzOut = new GzipCompressorOutputStream(bOut);
        tOut = new TarArchiveOutputStream(gzOut);
        addFileToTarGz(tOut, dirPath, "");
    } finally {
        tOut.finish();
        tOut.close();
        gzOut.close();
        bOut.close();
        fOut.close();
    }
}

private void addFileToTarGz(TarArchiveOutputStream tOut, String path, String base)
    throws IOException
{
    File f = new File(path);
    System.out.println(f.exists());
    String entryName = base + f.getName();
    TarArchiveEntry tarEntry = new TarArchiveEntry(f, entryName);
    tOut.putArchiveEntry(tarEntry);

    if (f.isFile()) {
        IOUtils.copy(new FileInputStream(f), tOut);
        tOut.closeArchiveEntry();
    } else {
        tOut.closeArchiveEntry();
        File[] children = f.listFiles();
        if (children != null) {
            for (File child : children) {
                System.out.println(child.getName());
                addFileToTarGz(tOut, child.getAbsolutePath(), entryName + "/");
            }
        }
    }
}
樊博雅
2023-03-14

我遵循这个解决方案,它一直工作,直到我处理一个更大的文件集,它在处理15000 - 16000个文件后随机崩溃。下面一行泄漏了文件处理程序:

IOUtils.copy(new FileInputStream(f), tOut);

和代码在操作系统级别崩溃并显示“打开的文件太多”错误以下小改动可解决问题:

FileInputStream in = new FileInputStream(f);
IOUtils.copy(in, tOut);
in.close();
 类似资料:
  • 我有一个档案 *.tar.gz 如何将其解压缩到目标目录?

  • 我正在使用Apache Commons Compress创建tar归档并解压它们。我的问题从这个方法开始:

  • 我正在使用commons-compress来处理tarball文件,并且注意到即使不是tar的文件似乎也会被处理。这是为什么--有没有更好的库来检测有效的tar文件 是一个CSV文件,测试失败,因为te.isFile()显然返回true。getName()似乎返回CSV的内容。这是不是我错误地使用了包的一个错误--我希望InputStream不能成功地转换为TarchiveEntry

  • 问题内容: 我想将普通文件压缩为.zip,然后将其压缩为gzip文件,而不创建新文件。 例如,假设我有一个pdf文档 doc.pdf ,我必须得到的是: 我不想创建一个名为的新文件,然后将其打开并gzip。 我正在与服务器一起从浏览器获取文件并将其返回,这是我的功能: 我得到了一个文件,但是它有一个损坏的文件并且没有压缩,为什么? 问题答案: 我认为您可以为zip创建一个临时文件,将其添加到gzi

  • 我有一个学校作业,要求我接受一个输入流,并使用apache commons压缩库将其压缩成一个字节数组,格式有5种(根据用户规范)。这5种格式是:ZIP、JAR、SEVENZ、BZIP2和gzip。我编写了以下方法以JAR格式压缩输入流,但得到了一个带有字符串“no current entry”的illegalStateException。

  • 我正在开发一个从tar获取信息的软件。gz文件,我正在使用Apache commons压缩库。但我得到了以下错误: 样品焦油。使用的gz文件是eclipse-jee-luna-SR1-linux-gtk-x86_64.tar.gz 下面是使用 lib 的类: