Очистка boost::iostreams::zlib_compressor.Как получить «синхронизацию»?
-
20-09-2019 - |
Вопрос
Требуется ли какая-то магия, чтобы получить "промывка синхронизации zlib" когда используешь boost::iostreams::zlib_compressor
?Просто вызов flush
на фильтре или strict_sync
на filtering_ostream
содержащий его не выполняет свою работу (т. е. я хочу, чтобы компрессор очистил достаточно, чтобы декомпрессор мог восстановить все байты, использованные компрессором на данный момент, не закрывая поток).
Глядя на заголовок, похоже, определены некоторые «коды сброса» (в частности, sync_flush
), но мне непонятно, как их следует использовать (учитывая, что мой компрессор просто добавлен в filtering_ostream
).
Решение
Оказывается, существует фундаментальная проблема: symmetric_filter
чтоzlib_compressor
наследует от не смывается сам (который, кажется, довольно
надзор).
Возможно добавление такой поддержки в symmetric_filter
было бы так же просто, как добавить flushable_tag
и раскрытие существующих частных методов очистки, но пока я могу с этим жить.
Другие советы
Эта библиотека обертки C ++ Zlib, из которой я автор, поддерживает функциональность промывки и, возможно, проще в использовании:
https://github.com/rudi-cilibrasi/zlibcomplete
Это так просто, как это:
#include <iostream>
#include <zlc/zlibcomplete.hpp>
using namespace zlibcomplete;
using namespace std;
int main(int argc, char **argv)
{
const int CHUNK = 16384;
char inbuf[CHUNK];
int readBytes;
ZLibCompressor compressor(9, auto_flush);
for (;;) {
cin.read(inbuf, CHUNK);
readBytes = cin.gcount();
if (readBytes == 0) {
break;
}
string input(inbuf, readBytes);
cout << compressor.compress(input);
}
cout << compressor.finish();
return 0;
}
Основное отличие от Boost заключается в том, что вместо использования фильтра класса шаблонов вы просто проходите в строку и записываете сжатую строку, которая приводит к тому, что вы захотите. Каждая строка будет промыть (в режиме auto_flush), поэтому ее можно использовать в интерактивных сетевых протоколах. В конце концов, просто вызовите, чтобы получить последний бит сжатых данных и блок завершения. Хотя пример Boost короче, он требует использования двух других классов шаблонов, которые не так известны, как std :: string, а именно Filtering_streambuf и менее стандартный Boost :: iostreams: копировать. Интерфейс Boost для Zlib неполный в том смысле, что он не поддерживает Z_SYNC_FLUSH. Это означает, что он не подходит для онлайн -приложений потоковой передачи, таких как в интерактивных протоколах TCP. Я люблю повысить и использовать его в качестве моей основной библиотеки поддержки C ++ во всех моих проектах C ++, но в данном конкретном случае это не было использовано в моем приложении из -за отсутствующей функциональности Flush.