boost gzip распаковывает байтовый массив
Я реализовал распаковку файлов gzip/zlib, как показано в их примерах на сайте поддержки.
void CompressionUtils::Inflate(std::ifstream& inputFile,
std::ofstream& outputFile)
{
boost::iostreams::filtering_streambuf<boost::iostreams::input> in;
in.push(boost::iostreams::gzip_decompressor());
in.push(inputFile);
boost::iostreams::copy(in, outputFile);
}
это отлично работает Я также читаю данные из сокета, который я получаю от службы JSON, основанной на отдыхе, которая также сжимается. Я подумал, что напишу реализацию на основе памяти, насколько это может быть сложно. Ну, я понял, что не понимаю потоки и потоковые буферы так, как должен. Я обвиняю последние несколько лет в Java;) .. Так что я пошел по этому пути.
void CompressionUtils::Inflate(char* compressed,
int size,
char* decompressed)
{
boost::iostreams::stream<boost::iostreams::array_source> source(compressed,size);
//std::stringstream str;
boost::iostreams::filtering_streambuf<boost::iostreams::input> in;
in.push(boost::iostreams::gzip_decompressor());
in.push(source);
//boost::iostreams::copy(in, str);
}
Но я в недоумении относительно того, какой поток я могу использовать, чтобы в основном получить распакованный char*
представление распакованного потока. Это должно быть легко, и, вероятно, так и есть, но последние пару часов я тратил впустую на неудачные попытки.
1 ответ
Очевидно, вы сталкивались с фильтрацией потоков и потоковыми буферами. Вы можете использовать тот же метод в обратном порядке, чтобы получить данные в строку.
У меня нет собственных удобных примеров, поэтому считаю, что это несколько псевдокод, но это должно быть то, что вы ищете:
namespace io = boost::iostreams; //<-- good practice
typedef std::vector<char> buffer_t;
void CompressionUtils::Inflate(const buffer_t &compressed,
buffer_t &decompressed)
{
io::filtering_ostream os;
os.push(io::gzip_decompressor());
os.push(io::back_inserter(decompressed));
io::write(os, &compressed[0], compressed.size());
}
Таким образом, вы можете использовать заднюю вставку, предоставленную Boost.
По сути, вышеприведенный код определяет выходной поток, в который вы можете писать. Он настроен так, что весь записанный в него контент сначала будет распакован gzip
, а затем добавляется к back_inserter
который, как и back_inserters, будет вставлен в конец decompressed
буфер.
Кроме того, как вы можете видеть, буферы обернуты в std::vector
, Дайте мне знать, если это работает для вас.