从流媒体存档中即时解压缩和提取文件

时间:2009-07-21 15:35:42

标签: c++ compression streaming archive

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

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

是否有支持此功能的格式/库?

编辑:如果可能的话,我更喜欢单个文件格式而不是单独的文件格式用于压缩和存档,例如gz / bzip2和tar。

3 个答案:

答案 0 :(得分:6)

这里有2个问题

  1. 如何编写代码。

  2. 使用何种格式。

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

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

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

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

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

    在要编写的代码上,

    O3D执行此操作并且是开源的,因此您可以查看代码 http://o3d.googlecode.com

    解压缩代码在o3d / import / cross /...

    它使用一些胶水定位NPAPI,可以在o3d / plugin / cross

    中找到

答案 1 :(得分:5)

查看boost::zlib filters。他们快速使用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);
}

答案 2 :(得分:2)

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

对于从存档中进行的增量提取(当它被缩小时),请查看例如:好的旧tar格式。