Получить размер несжатых данных в zlib? - PullRequest
5 голосов
/ 30 мая 2009

Я создаю что-то, что включает в себя своего рода службу загрузки файлов, и мне нужно хранить данные, сжатые функцией zlib compress () Я отправляю его через Интернет уже сжатым, но мне нужно знать размер несжатого файла на удаленном сервере. Можно ли как-то выяснить эту информацию, не распаковывая сначала данные на сервере, просто для эффективности? Вот как я это делаю сейчас, но если есть ярлык, я бы с удовольствием его принял.

Кстати, а почему это называется несжатый? Это звучит довольно ужасно для меня, я всегда думал, что это будет распаковка ...

Ответы [ 3 ]

4 голосов
/ 30 мая 2009

Если вы загружаете в формате raw, тогда у вас не будет информации о размере загружаемых данных. Пакс прав в этом отношении.
Вы можете сохранить его как 4-байтовый заголовок в начале буфера сжатия - при условии, что размер файла не превышает 4 ГБ.
немного кода C в качестве примера:

 uint8_t *compressBuffer = calloc(bufsize + sizeof (uLongf), 0);
 uLongf compressedSize = bufsize;
 *((uLongf *)compressBuffer) = filesize;
 compress(compressBuffer + sizeof (uLongf), &compressedSize, sourceBuffer, bufsize);

Затем вы отправляете полный сжатый буфер размера сжатого размера + размер (uLongf). Когда вы получите его на стороне сервера, вы можете использовать следующий код для получения данных:

 // data is in compressBuffer, assume you already know compressed size.
 uLongf originalSize = *((uLongf *)compressBuffer);
 uint8_t *realCompressBuffer = compressBuffer + sizeof (uLongf);

Если вы не доверяете клиенту при отправке правильного размера, вам потребуется выполнить некую проверку несжатых данных о размере сервера. Предложение использовать uncompress для / dev / null является разумным.
Если вы загружаете файл .zip, он содержит каталог, в котором указывается размер файла в несжатом виде. Эта информация опять-таки встроена в формат файла, хотя она может быть использована злонамеренными клиентами.

4 голосов
/ 30 мая 2009

Я сомневаюсь в этом. Я не верю, что это то, что библиотеки zlib предоставляют из памяти (хотя прошло уже 7 или 8 лет с тех пор, как я его использовал, современные документы, похоже, не указывают на то, что эта функция была добавлена).

Одной из возможностей может быть передача другого файла, который содержал бы несжатый размер (например, как file.zip, так и file.zip.size), но который представляет опасность, особенно если вы ошиблись в размере.

Другой альтернативой является то, что если распаковка сервера является дорогостоящей, но не требует немедленного выполнения, выполните это в фоновой задаче с более низким приоритетом (как в случае nice в Linux). Но опять же, могут быть недостатки, если проверка размера начинает выполняться сзади (слишком много загрузок).

И я склонен думать о декомпрессии в терминах «взрывной декомпрессии», а не о том, что лучше использовать: -)

3 голосов
/ 30 мая 2009

В формате zlib нет поля для исходного размера ввода, поэтому я сомневаюсь, что вы сможете сделать это без симуляции декомпрессии данных. формат gzip имеет поле «Размер ввода» (ISIZE), которое вы можете использовать, но, возможно, вы хотите избежать изменения формата сжатия или иметь клиентов, отправляющих размер файла.

Но даже если вы используете другой формат, если вы не доверяете клиентам, вам все равно нужно будет выполнить более дорогую проверку, чтобы убедиться, что несжатые данные соответствуют размеру, который, по словам клиента, они имеют. В этом случае вы можете сделать процесс uncompress-to- / dev / null менее дорогостоящим, убедившись, что zlib нигде не записывает выходные данные, поскольку вы просто хотите знать несжатый файл. размер.

...