Распаковка и извлечение файлов из потокового архива "на лету"

StackOverflow https://stackoverflow.com/questions/1159992

Вопрос

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

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

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

Редактировать: Если возможно, я бы предпочел единый формат файла вместо отдельных для сжатия и архивирования, таких как gz / bzip2 и tar.

Это было полезно?

Решение

Здесь есть 2 проблемы

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

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

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

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

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

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

У Gzipped tar-файлов этой проблемы нет.Файлы Tar хранятся в виде заголовка, файла, файла заголовка, и, кроме того, выполняется сжатие, так что можно распаковывать загруженный файл по мере его загрузки и использовать файлы по мере их появления.Вы можете легко создавать файлы gzipped tar в Windows с помощью winrar (коммерческий) или 7-zip (бесплатный), а в Linux, osx и cygwin использовать команду tar.

О коде, который нужно написать,

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

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

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

Другие советы

Посмотрите на boost:: фильтры zlib.Они делают, используя zlib щелчок.

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

#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);
}

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top