Промывка повышения :: iostreams :: zlib_compressor. Как получить «синхронную очистку»? - PullRequest
5 голосов
/ 18 марта 2010

Требуется ли какое-нибудь волшебство для получения "zlib sync flush" при использовании boost::iostreams::zlib_compressor? Просто вызов flush на фильтре или strict_sync на filtering_ostream, содержащем его, не позволяет выполнить работу (т. Е. Я хочу, чтобы компрессор очищался достаточно, чтобы декомпрессор мог восстановить все байты, использованные компрессором, так что далеко, не закрывая поток).

Глядя на заголовок , кажется, что определены некоторые "коды сброса" (в частности, sync_flush), но мне неясно, как их использовать (учитывая, что мой компрессор только что добавлен в filtering_ostream).

Ответы [ 2 ]

2 голосов
/ 12 апреля 2010

Оказывается, есть фундаментальная проблема, что symmetric_filter, что zlib_compressor наследует от самого себя (не кажется недосмотр).

Возможно, добавить такую ​​поддержку к symmetric_filter будет так же просто, как добавить flushable_tag и раскрыть существующие методы приватного сброса, но сейчас я могу с этим жить.

0 голосов
/ 08 июля 2015

Эта библиотека оболочки 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), чтобы ее можно было использовать в интерактивных сетевых протоколах. В конце просто вызовите Finish, чтобы получить последний бит сжатых данных и блок завершения. Хотя пример boost короче, он требует использования двух других классов шаблонов, которые не так хорошо известны как std :: string, а именно: filtering_streambuf и менее стандартный boost :: iostreams: copy. Интерфейс буста для zlib неполон в том, что он не поддерживает Z_SYNC_FLUSH. Это означает, что он не подходит для потоковых приложений, таких как интерактивные протоколы TCP. Я люблю boost и использую ее как основную библиотеку поддержки C ++ во всех моих проектах C ++, но в данном конкретном случае ее нельзя было использовать в моем приложении из-за отсутствующей функции сброса.

...