Как предположить, какой будет размер после распаковки zlib? - PullRequest
0 голосов
/ 07 февраля 2019

Я делаю простое приложение на C ++, которое должно отправлять сжатые данные в мой API.API запускает ответ в приложении, которое также сжато.Я должен распаковать это.Я использую функцию распаковки zlib, но я не знаю, насколько большие данные.Может ли кто-нибудь помочь мне с этой проблемой?Как я могу рассчитать и установить размер буфера назначения?

Ответы [ 2 ]

0 голосов
/ 08 февраля 2019

В качестве оптимизации скорости, если вы хотите время от времени выполнять избыточные вызовы для распаковки, вы можете предсказать размер буфера dest для следующего вызова.Часто бывает так, что сегменты данных в данном потоке сжимаются примерно на один и тот же коэффициент.Например, текст будет сжат в 2–3 раза.Поэтому запишите где-нибудь последний размер вашего буфера dest.Затем выделите ту же сумму для следующего несжатого вызова.Если слишком мало (Z_BUF_ERROR), то увеличьте размер буфера и повторите.Если слишком много буферного пространства, проблем нет;просто уменьшите размер для следующего вызова.

Вот дополнительная оптимизация.Предположим, ваше назначение будет очень большим, скажем, гигабайтами.И вы не хотите тратить впустую циклы процессора, делая пробные распаковки.Вы можете кормить только первые несколько сотен килобайт ваших исходных данных и посмотреть, насколько они расширяются.Затем выделите фактический буфер назначения соответственно.Я не знаю, позволит ли uncompress () вам это сделать, но inflate () позволит.

0 голосов
/ 07 февраля 2019

Я думаю, что документация действительно ясна об этом

ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen,
                               const Bytef *source, uLong sourceLen));

Распаковывает исходный буфер в целевой буфер.sourceLen - длина байта исходного буфера. При входе destLen - это общий размер буфера назначения, который должен быть достаточно большим, чтобы вместить все несжатые данные.(Размер несжатых данных должен быть предварительно сохранен компрессором и передан в декомпрессор каким-либо механизмом вне области действия этой библиотеки сжатия.) При выходе destLen - это фактический размер несжатых данных.

uncompress возвращает Z_OK в случае успеха, Z_MEM_ERROR, если не было достаточно памяти, Z_BUF_ERROR, если в выходном буфере недостаточно места, или Z_DATA_ERROR, если входные данные были повреждены или неполны.В случае, когда недостаточно места, uncompress () заполнит выходной буфер несжатыми данными до этой точки.

Поэтому zlib рекомендует отправлять несжатый размер вместе со сжатым потоком.

Но мы также можем отметить предложение

В случае, когда недостаточно места, uncompress () заполнит выходной буфер несжатыми данными до этой точки.

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

В зависимости от вашего варианта использования это может быть хорошей идеей или нет.Если размеры вашего сообщения не сильно различаются и программа работает дольше, может быть, лучше просто сохранить один целевой буфер и просто увеличивать его по мере необходимости.

...