从嵌入式ZIP存档中读取文件

7
我有一个嵌入在较大文件中的ZIP归档文件。我知道归档文件在较大文件中的起始偏移量和长度。
是否有任何Java库可以使我直接读取归档文件中包含的文件?我考虑类似于ZipFile.getInputStream()的方法。不幸的是,ZipFile对于此用例无法工作,因为它的构造函数需要一个独立的ZIP文件。
出于性能原因,在打开ZIP归档文件之前,我不能将其复制到单独的文件中。 编辑:只是为了明确,我确实可以随机访问该文件。

java.util.zip.ZipInputStream.ZipInputStream(InputStream)的翻译是什么? - artbristol
有些困难。对于 ZIP 文件,您需要先读取目录,而该目录位于末尾,因此您需要进行随机访问。您可以一次性从开头读取所有条目,并且这适用于大多数 zip 文件,但是该格式本身允许出现重复条目和条目之间的随机垃圾数据等奇怪的情况。 - Thilo
@Thilo:只是为了明确,我确实可以随机访问该文件。 - NPE
7个回答

7

我想出了一个快速的技巧(需要在某些地方进行清理),但它可以从嵌入在TAR文件中的ZIP存档中读取文件内容。 它使用Java6,FileInputStream,ZipEntry和ZipInputStream。"在我的本地机器上工作":

final FileInputStream ins = new FileInputStream("archive.tar");
// Zip starts at 0x1f6400, size is not needed
long toSkip = 0x1f6400;
// Safe skipping
while(toSkip > 0)
    toSkip -= ins.skip(toSkip);

final ZipInputStream zipin = new ZipInputStream(ins);
ZipEntry ze;
while((ze = zipin.getNextEntry()) != null)
{
    final byte[] content = new byte[(int)ze.getSize()];
    int offset = 0;
    while(offset < content.length)
    {
        final int read = zipin.read(content, offset, content.length - offset);
        if(read == -1)
            break;
        offset += read;
    }
    // DEBUG: print out ZIP entry name and filesize
    System.out.println(ze + ": " + offset);
}
zipin.close();

1

我建议使用TrueZIP,它可以提供对许多种类型的存档文件的文件系统访问。在过去,它为我工作得很好。


1

1.创建FileInputStream对象:FileInputStream fis = new FileInputStream(..);

  1. 将其定位到嵌入式zip文件的开头位置: fis.skip(offset);

  2. 打开ZipInputStream(fis)


这应该适用于大多数文件,但zip文件格式允许出现重复条目和随机垃圾数据,因此最好具有随机访问功能,并首先读取存档末尾的目录。 - Thilo

0

0

我认为 Apache Commons Compress 可以帮助你。

它有一个类 org.apache.commons.compress.archivers.zip.ZipArchiveEntry,它继承了 java.util.zip.ZipEntry

它还有一个方法 getDataOffset(),可以获取归档文件中数据流的偏移量。


-1

检查一下zip4j是否能够帮助您。

根据您的用例,您可以尝试使用PartInputStream来读取zip文件。

我认为最好创建临时zip文件,然后再进行访问。


-1

7-zip-JavaBinding7-zip C++ 库的 Java 封装。

特别是 代码片段 页面,其中包含一些不错的示例,包括打印存档中项目列表、提取单个文件和打开多部分存档。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接