Я использую boost::iostreams::gzip_decompressor
с boost::iostreams::filterimg_streambuf
для чтения файлов gzip.
некоторые из моих файлов имеют то, что zcat
называет trailing trash
% zcat somefile
data
data
data
gzip: somefile: decompression OK, trailing garbage ignored
Я хочу, чтобы boost gzip вел себя так же.
При попытке распаковать тот же файл с помощью boost, используя следующую функцию, я получаю исключение gzip_error (bad_header)
static int read_gzip(fs::path f, stringstream& s)
{
ifstream file(f.string().c_str(), ios_base::in | ios_base::binary);
io::filtering_streambuf<io::input> in;
in.push(io::gzip_decompressor());
in.push(file);
try {
io::copy(in, s);
return 1;
}
catch (io::gzip_error& e) {
fprintf(stderr, "(read_gzip) io::copy exception %s %s (%d)\n", f.string().c_str(), e.what(), e.error());
}
return 0;
}
когда выдается исключение, stingstream
остается пустым.
В качестве обходного пути я могу прочитать данные побайтно, используя что-то вроде этого:
static int read_gzip(fs::path f, string& s)
{
ifstream file(f.string().c_str(), ios_base::in | ios_base::binary);
io::filtering_streambuf<io::input> in;
char buf[1];
in.push(io::gzip_decompressor());
in.push(file);
try {
std::streamsize result;
while ((result = io::read(in, buf, 1)) != -1) {
s.append(buf, 1);
}
return 1;
}
catch (io::gzip_error& e) {
fprintf(stderr, "(read_gzip) io::copy exception %s %s (%d)\n", f.string().c_str(), e.what(), e.error());
}
return 0;
}
но это кажется довольно неэффективным.
Как правильно читать сжатые файлы с конечным мусором?
Спасибо.