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

发布于 2024-07-27 03:33:22 字数 335 浏览 7 评论 0原文

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

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

有支持这个的格式/库吗?

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

I'm writing a browser plugin, similiar to Flash and Java in that it starts downloading a file (.jar or .swf) as soon as it gets displayed. Java waits (I believe) until the entire jar files is loaded, but Flash does not. I want the same ability, but with a compressed archive file. I would like to access files in the archive as soon as the bytes necessary for their decompression are downloaded.

For example I'm downloading the archive into a memory buffer, and as soon as the first file is possible to decompress, I want to be able to decompress it (also to a memory buffer).

Are there any formats/libraries that support this?

EDIT: If possible, I'd prefer a single file format instead of separate ones for compression and archiving, like gz/bzip2 and tar.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

痴者 2024-08-03 03:33:22

这里有2个问题

  1. 如何编写代码。

  2. 使用什么格式。

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

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

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

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

Gzip 压缩的 tar 文件不存在此问题。 Tar 文件存储了标头、文件、标头文件,压缩位于其之上,因此可以在下载文件时对其进行解压缩,并在文件可用时使用它们。 您可以在 Windows 中使用 winrar(商业)或 7-zip(免费)轻松创建 gzip 压缩的 tar 文件,在 Linux、osx 和 cygwin 上使用 tar 命令。

关于要写的代码,

O3D就是这样做的,并且是开源的,所以你可以看一下代码
http://o3d.googlecode.com

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

中使用一些胶水来定位 NPAPI,这些胶水可以在 o3d/plugin/cross 中找到

There are 2 issues here

  1. How to write the code.

  2. What format to use.

On the file format, You can't use the .ZIP format because .ZIP puts the table of contents at the end of the file. That means you'd have to download the entire file before you can know what's in it. Zip has headers you can scan for but those headers are not the official list of what's in the file.

Zip explicitly puts the table of contents at the end because it allows fast adding a files.

Assume you have a zip file with contains files 'a', 'b', and 'c'. You want to update 'c'. It's perfectly valid in zip to read the table of contents, append the new c, write a new table of contents pointing to the new 'c' but the old 'c' is still in the file. If you scan for headers you'll end up seeing the old 'c' since it's still in the file.

This feature of appending was an explicit design goal of zip. It comes from the 1980s when a zip could span multiple floppy discs. If you needed to add a file it would suck to have to read all N discs just to re-write the entire zip file. So instead the format just lets you append updated files to the end which means it only needs the last disc. It just reads the old TOC, appends the new files, writes a new TOC.

Gzipped tar files don't have this problem. Tar files are stored header, file, header file, and the compression is on top of that so it's possible to decompress as the file it's downloaded and use the files as they become available. You can create gzipped tar files easily in windows using winrar (commercial) or 7-zip (free) and on linux, osx and cygwin use the tar command.

On the code to write,

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

不可一世的女人 2024-08-03 03:33:22

查看 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);
}

Check out the boost::zlib filters. They make using zlib a snap.

Here's the sample from the boost docs that will decompress a file and write it to the console:

#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);
}
2024-08-03 03:33:22

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

要从存档中增量提取(当它缩小时),请查看例如旧的 tar< /a> 格式。

Sure, zlib for example uses z_stream for incremental compression and decompression via functions inflateInit, inflate, deflateInit, deflate. libzip2 has similar abilities.

For incremental extraction from the archive (as it gets deflated), look e.g. to the good old tar format.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文