6

我正在编写一个浏览器插件,与 Flash 和 Java 类似,它会在文件显示后立即开始下载文件(.jar 或 .swf)。Java 等待(我相信)直到整个 jar 文件被加载,但 Flash 没有。我想要同样的能力,但需要一个压缩的存档文件。一旦下载了解压缩所需的字节,我想访问存档中的文件。

例如,我正在将存档下载到内存缓冲区,一旦第一个文件可以解压缩,我希望能够将其解压缩(也可以解压缩到内存缓冲区)。

是否有任何格式/库支持这一点?

编辑:如果可能的话,我更喜欢单一的文件格式而不是单独的文件格式来压缩和归档,比如 gz/bzip2 和 tar。

4

3 回答 3

6

这里有2个问题

  1. 如何编写代码。

  2. 使用什么格式。

在文件格式上,您不能使用 .ZIP 格式,因为 .ZIP 将目录放在文件末尾。这意味着您必须先下载整个文件,然后才能知道其中的内容。Zip 有您可以扫描的标题,但这些标题不是文件中内容的官方列表。

Zip 明确地将目录放在最后,因为它允许快速添加文件。

假设您有一个包含文件“a”、“b”和“c”的 zip 文件。你想更新'c'。在 zip 中读取目录、附加新的 c、写入指向新的“c”但旧的“c”仍在文件中的新目录是完全有效的。如果您扫描标题,您最终会看到旧的“c”,因为它仍在文件中。

附加功能是 zip 的明确设计目标。它来自 1980 年代,当时一个 zip 可以跨越多个软盘。如果您需要添加一个文件,那么为了重新写入整个 zip 文件而必须读取所有 N 盘是很糟糕的。因此,该格式只允许您将更新的文件附加到末尾,这意味着它只需要最后一张光盘。它只是读取旧的 TOC,附加新文件,写入新的 TOC。

Gzipped tar 文件没有这个问题。Tar 文件存储头、文件、头文件,并且压缩是最重要的,因此可以将其作为下载的文件解压缩并在文件可用时使用它们。您可以在 windows 中使用 winrar(商业)或 7-zip(免费)轻松创建 gzipped tar 文件,在 linux、osx 和 cygwin 上使用 tar 命令。

关于要写的代码,

O3D does this and is open source so you can look at the code http://o3d.googlecode.com

The decompression code is in o3d/import/cross/...

It targets the NPAPI using some glue which can be found in o3d/plugin/cross

于 2009-07-21T19:44:42.233 回答
5

查看boost::zlib 过滤器。他们使使用zlib变得轻而易举。

这是来自 boost 文档的示例,它将解压缩文件并将其写入控制台:

#include <fstream>
#include <iostream>
#include <boost/iostreams/filtering_streambuf.hpp>
#include <boost/iostreams/copy.hpp>
#include <boost/iostreams/filter/zlib.hpp>

int main() 
{
    using namespace std;

    ifstream file("hello.z", ios_base::in | ios_base::binary);
    filtering_streambuf<input> in;
    in.push(zlib_decompressor());
    in.push(file);
    boost::iostreams::copy(in, cout);
}
于 2009-07-21T15:40:52.320 回答
2

当然,例如zlib通过函数 inflateInit、inflate、deflateInit、deflate 使用z_stream进行增量压缩和解压缩。libzip2具有类似的能力。

对于从存档中增量提取(因为它被压缩),请查看例如良好的旧tar格式。

于 2009-07-21T15:39:43.600 回答