当前位置: 首页 > 面试题库 >

使用与机器无关的Apache Commons Compress库将文件和库添加到Tar归档文件中

谷梁子濯
2023-03-14
问题内容

我正在开发一个需要创建tar存档以计算其哈希值的应用程序。但是我遇到一些问题:

  • tar在不同的机器上不一样,则计算出的哈希值不同
  • 我无法正确添加目录
  • 如果我在tar的最后添加一个zip文件,则我的zip文件中的内容不存在:/

我已经阅读了SO中的不同文章以及有关apache的专用教程,还阅读了apache commons compress
jar的源测试代码,但是我没有找到正确的解决方案。

是否有人可以找到我的代码不正确的地方?

    public static File createTarFile(File[] files, File repository) {
    File tarFile = new File(TEMP_DIR + File.separator + repository.getName() + Constants.TAR_EXTENSION);
    if (tarFile.exists()) {
        tarFile.delete();
    }

    try {
        OutputStream out = new FileOutputStream(tarFile);

        TarArchiveOutputStream aos = (TarArchiveOutputStream) new ArchiveStreamFactory().createArchiveOutputStream("tar", out);

        for(File file : files){
            Utilities.addFileToTar(aos, file, "");
        }

        aos.finish();
        aos.close();
        out.close();
    } catch (Exception e) {
        e.printStackTrace();
    }

    return tarFile;
}

private static void addFileToTar(TarArchiveOutputStream tOut, File file, String base) throws IOException {

    TarArchiveEntry entry = new TarArchiveEntry(file, base + file.getName());
    entry.setModTime(0);
    entry.setSize(file.length());
    entry.setUserId(0);
    entry.setGroupId(0);
    entry.setUserName("avalon");
    entry.setGroupName("excalibur");
    entry.setMode(0100000);
    entry.setSize(file.length());
    tOut.putArchiveEntry(entry);

    if (file.isFile()) {
        IOUtils.copy(new FileInputStream(file), tOut);
        tOut.closeArchiveEntry();
    } else {
        tOut.closeArchiveEntry();
        File[] children = file.listFiles();
        if (children != null) {
            for (File child : children) {
                addFileToTar(tOut, child, file.getName());
            }
        }
    }
}

谢谢。


问题答案:

在阅读caarlos0的帖子后,我终于找到了解决方案:在Linux上使用ApacheCommonsCompression压缩文件时出现编码问题
由于某种原因,java不尊重我环境的编码,而是将其更改为cp1252。

之后,我解压缩文件,我只需要在其中输入文件夹,然后运行以下命令:

convmv --notest -f cp1252 -t utf8 * -r

并将所有内容递归转换为UTF-8。

伙计们,问题解决了。

使用apache-commons-1.8.jar库,我制作了一个可以完成此工作的工具类:

您可以在这里找到此代码:MakeTar库的GitHub存储库

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;
import org.apache.commons.compress.utils.IOUtils;

/**
 * The Class TarArchive.
 */
public class TarArchive {

    /**
     * Creates the tar of files.
     *
     * @param files the files
     * @param tarPath the tar path
     * @throws IOException Signals that an I/O exception has occurred.
     */
    public static void createTarOfFiles(String[] files, String tarPath) throws IOException
    {
        FileOutputStream fOut = null;
        BufferedOutputStream bOut = null;
        TarArchiveOutputStream tOut = null;

        Arrays.sort(files);
        try
        {
            fOut = new FileOutputStream(new File(tarPath));
            bOut = new BufferedOutputStream(fOut);
            tOut = new TarArchiveOutputStream(bOut);

            for (String file : files) {
                addFileToTar(tOut, file, "");
            }
        }
        finally
        {
            tOut.finish();
            tOut.close();
            bOut.close();
            fOut.close();
        }
    }

    /**
     * Creates the tar of directory.
     *
     * @param directoryPath the directory path
     * @param tarPath the tar path
     * @throws IOException Signals that an I/O exception has occurred.
     */
    public static void createTarOfDirectory(String directoryPath, String tarPath) throws IOException
    {
        FileOutputStream fOut = null;
        BufferedOutputStream bOut = null;
        TarArchiveOutputStream tOut = null;

        try
        {
            fOut = new FileOutputStream(new File(tarPath));
            bOut = new BufferedOutputStream(fOut);
            tOut = new TarArchiveOutputStream(bOut);

            addFileToTar(tOut, directoryPath, "");
        }
        finally
        {
            tOut.finish();
            tOut.close();
            bOut.close();
            fOut.close();
        }
    }

    /**
     * Adds the file to tar.
     *
     * @param tOut the t out
     * @param path the path
     * @param base the base
     * @throws IOException Signals that an I/O exception has occurred.
     */
    private static void addFileToTar(TarArchiveOutputStream tOut, String path, String base) throws IOException
    {
        File f = new File(path);
        String entryName = base + f.getName();
        TarArchiveEntry tarEntry = new TarArchiveEntry(f, entryName);

        tOut.setLongFileMode(TarArchiveOutputStream.LONGFILE_GNU);

        if(f.isFile())
        {
           tarEntry.setModTime(0);
           tOut.putArchiveEntry(tarEntry);

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

           tOut.closeArchiveEntry();
        }
        else
        {
            File[] children = f.listFiles();
            Arrays.sort(children);

            if(children != null)
            {
                for(File child : children)
                {
                    addFileToTar(tOut, child.getAbsolutePath(), entryName + "/");
                }
            }
        }
    }
}

感谢您阅读我。

编辑:很少的校正,我已经添加了数组的种类。

编辑2:我已更正代码,以便在所有计算机上具有相同的存档。存档上计算的哈希值在任何地方都是相同的。



 类似资料:
  • 问题内容: 如何在Go中将文件附加到现有的tar存档中?我没有在文档中看到任何明显的方法。 我有一个已经创建的tar文件,在关闭它之后,我想向它添加更多文件。 编辑 更改文档中的示例并遵循给出的答案,我仍然没有得到预期的结果。前三个文件正在写入tar,但是当我再次关闭并打开文件以对其进行写入时,永远不会写入新文件。代码运行正常。我不知道我在想什么。 以下代码为我提供了一个tar文件,其中包含三个文

  • 我阅读了如何在java中将文件附加到tar存档?,将文件附加到存档而无需读取/重写整个存档,并在不覆盖其现有内容的情况下将条目添加到tar文件,但没有给出好的答案。此外,我没有足够的声誉来发表评论。所以我在这里创建了一个新问题。 有没有办法将文件附加到tar存档中?如果文件已经存在,我想替换它。 我已经开始编写下面的方法,但是当添加文件时,它会删除存档内容。我在apache compress网站上

  • 我正在处理一个应用程序,它需要创建一个tar归档,以便计算他的散列。但我遇到了一些问题: 不同计算机的tar不相同,则计算的哈希也不同 无法正确添加目录 如果我在tar的末尾添加了一个zip文件,那么我就可以从zip文件中获取内容:/ 有没有人能找到我的代码不正确的地方? 谢谢你。

  • 问题内容: 我正在做一个Maven项目。当在一个想法中编译和运行我的项目时,一切都很好,但是每当我创建jar文件时,都无法将web / lib /中的外部jar文件复制到jar文件中。为什么会发生这种情况?我可以将所有文件插入jar文件吗? 问题答案: 是的,我找到了解决方案。

  • 我有一个问题,我需要将文件附加到媒体库中的文档。 开箱即用Kentico似乎只允许在附件部分和相关文档上直接上传,您只能在网站上关联其他内容/文档。 我希望能够将文件作为相关文档或媒体库的附件附加。 我在网上找这个,但我什么也找不到。 我目前的计划是在“添加相关媒体文件”中添加一个自定义部分,但如果有更简单的方法,那就太好了。 为了澄清这一点,我需要能够将多个媒体文件添加到一个文档中。 当做

  • 本文向大家介绍Python3实现将文件树中所有文件和子目录归档到tar压缩文件的方法,包括了Python3实现将文件树中所有文件和子目录归档到tar压缩文件的方法的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了Python3实现将文件树中所有文件和子目录归档到tar压缩文件的方法。分享给大家供大家参考。具体实现方法如下: 希望本文所述对大家的Python3程序设计有所帮助。