Распаковка и извлечение файлов из потокового архива на лету - PullRequest
6 голосов
/ 21 июля 2009

Я пишу плагин для браузера, похожий на Flash и Java, который начинает загружать файл (.jar или .swf), как только он отображается. Java ждет (я полагаю), пока не загрузятся все файлы jar, а Flash - нет. Я хочу такую ​​же возможность, но со сжатым архивным файлом. Я хотел бы получить доступ к файлам в архиве, как только будут загружены байты, необходимые для их распаковки.

Например, я загружаю архив в буфер памяти, и как только можно распаковать первый файл, я хочу иметь возможность распаковать его (также в буфер памяти).

Существуют ли форматы / библиотеки, которые поддерживают это?

РЕДАКТИРОВАТЬ: Если возможно, я бы предпочел один формат файла вместо отдельных форматов для сжатия и архивирования, например, gz / bzip2 и tar.

Ответы [ 3 ]

6 голосов
/ 21 июля 2009

Здесь есть 2 вопроса

  1. Как написать код.

  2. Какой формат использовать.

В формате файла. Вы не можете использовать формат .ZIP, потому что .ZIP помещает оглавление в конец файла.Это означает, что вам нужно скачать весь файл, прежде чем вы сможете узнать, что в нем.У Zip есть заголовки, которые вы можете сканировать, но эти заголовки не являются официальным списком того, что находится в файле.

Zip явно ставит оглавление в конец, потому что позволяет быстро добавлять файлы.

Предположим, у вас есть zip-файл, содержащий файлы «a», «b» и «c».Вы хотите обновить «с».В zip вполне допустимо читать оглавление, добавлять новый c, записывать новое оглавление, указывающее на новое «c», но старый «c» все еще находится в файле.Если вы сканируете заголовки, вы в конечном итоге увидите старый символ «c», поскольку он все еще находится в файле.

Эта функция добавления была явной целью разработки zip.Это происходит с 1980-х годов, когда почтовый индекс может охватывать несколько дискет.Если вам нужно было добавить файл, было бы плохо, если бы вам пришлось читать все N дисков только для того, чтобы переписать весь zip-файл.Таким образом, вместо этого формат позволяет просто добавлять обновленные файлы в конец, что означает, что ему нужен только последний диск.Он просто читает старое оглавление, добавляет новые файлы и записывает новое оглавление.

GZIP-файлы tar не имеют этой проблемы.Тар-файлы хранятся в заголовке, файле, заголовочном файле, и сжатие поверх этого, так что можно распаковать его по мере загрузки и использовать файлы по мере их появления.Вы можете легко создавать gzip-файлы tar в Windows, используя winrar (коммерческий) или 7-zip (бесплатно), а в linux, osx и cygwin используйте команду tar.

В коде для записи

O3D делает это и является открытым исходным кодом, так что вы можете посмотреть на код http://o3d.googlecode.com

Код декомпрессии находится в o3d / import / cross /...

Он нацелен на NPAPI, используя некоторыеклей, который можно найти в o3d / plugin / cross

5 голосов
/ 21 июля 2009

Проверьте фильтры boost :: zlib . Они делают zlib оснасткой.

Вот пример из документов наддува, который распакует файл и запишет его в консоль:

#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 голосов
/ 21 июля 2009

Конечно, zlib , например, использует z_stream для инкрементного сжатия и распаковки с помощью функций inflateInit, inflate, deflateInit, deflate. libzip2 обладает подобными способностями.

Для инкрементного извлечения из архива (по мере его дефляции) смотрите, например, в старый добрый формат tar .

...