以编程方式从7zip存档中提取单个特定文件 - Java - Linux

时间:2016-12-12 23:36:56

标签: java linux 7zip

我非常感谢您对以下情况的意见。

要求: - 我有一个包含数千个文件的7zip存档文件 - 我有一个在linux上运行的java应用程序,需要从7 zip文件中检索单个文件

  • 我想通过其路径(例如my7zFile.7z / file1.pdf)从归档中检索文件,而无需遍历归档中的所有文件并比较文件名。

    < / LI>
  • 我想避免在运行搜索之前从存档中提取所有文件(未压缩的存档是几TB)。

我查看了7zip Java Binding - 特别是IInArchive类,唯一的提取方法似乎通过文件索引工作,而不是通过文件名:

http://sevenzipjbind.sourceforge.net/javadoc/net/sf/sevenzipjbinding/IInArchive.html

你知道其他任何可以帮助我解决这个用例的库吗?或者我是否忽略了使用7zip jbinding进行此操作的方法?

谢谢

亲切的问候,

托比

2 个答案:

答案 0 :(得分:1)

可悲的是,似乎API并没有提供足以满足您的所有要求。为了提取单个文件,您需要遍历归档索引。归档的简化界面使这更容易:

ISimpleInArchive界面提供:

ISimpleInArchiveItem[]  getArchiveItems()  

允许您检索存档中的项目列表。 ISimpleInArchiveItem接口提供了以下方法:

java.lang.String    getPath()

因此,您可以在路径上比较archiveItems。当然这是违反您要求的。

但是,请注意,这将遍历索引表,并且在请求之前不会提取文件。一旦你有了你可以使用的项目之后:

ExtractOperationResult  extractSlow(ISequentialOutStream SequentialOutStream) 

在您发现的实际提取它的项目上。

查看7z file format(注意这不是7zip的官方站点),标题信息全部位于文件的末尾,文件开头的Signature标题给出了一个偏移量标题信息。因此,如果SevenZip绑定编写得很好,您的搜索最多会读取文件的开头(SignatureHeader)以找到HeaderInfo部分的偏移量,然后遍历HeaderInfo部分以构建getArchiveItems()中所需的文件列表。只有当您拥有所需的项目时,它才会切换回您想要提取的文件的实际流的索引(最有可能在您调用extractSlow时)。

因此,虽然并非满足您的所有要求,但所需搜索/比较的开销仅限于搜索存档的标题信息。

答案 1 :(得分:0)

我写了一个代码,从zip文件中读取所有文件和文件夹。我在zip文件中有一个长文件(文本)/文件夹层次结构。我不确定这是否会对你有所帮助。我正在分享代码的骨架。

import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

ZipFile zipFile = new ZipFile(filepath); // filepath of the zip file
Enumeration<? extends ZipEntry> entries = zipFile.entries();

while (entries.hasMoreElements()) {
    ZipEntry entry = entries.nextElement();
    if (entry.isDirectory()) { // found directory inside the zipFile
        // write your code here
    } else {
        InputStream stream = zipFile.getInputStream(entry);
        BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
        // write your code to read the content of the file
    }
}

您可以修改代码,以便在zip中找到所需的文件。但我不认为您将能够直接访问该文件,而是必须遍历zip存档的所有路径。 请注意ZipFile以DFS(深度优先搜索)方式遍历压缩文件中的所有文件和文件夹。您将在网上找到详细的相关示例。