Вопрос

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

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

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

Решение

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

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

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

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

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

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

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

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

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

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

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

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

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