我们工作中的产品之一涉及其中具有以下结构的文件:
A STRING WITH SOME CONTENT IDENTIFYING THE FILES CONTENTS
A STRING ON ROW 2
A STRING ON ROW 3
A STRING ON ROW 4
<binary data starts here and is gzipped>
现在,如果我这样做,我可以解压缩内容并重新创建同一文件的未压缩版本:
INPUT=FILEA.COMPRESSED
OUTPUT=FILEB.UNCOMPRESSED
head -n5 $INPUT > $OUTPUT
cat $INPUT | tail --lines=+5 | gunzip >> $OUTPUT
# At this point I'm left with a file structure as follows:
A STRING WITH SOME CONTENT IDENTIFYING THE FILES CONTENTS
A STRING ON ROW 2
A STRING ON ROW 3
A STRING ON ROW 4
<uncompressed content>
我正在尝试通过提升来完成同样的壮举。Boost 总是抛出一个gzip_error代码4,gzip.hpp显示为bad_header。
毫无疑问,我正在处理的文件不是防弹的,并且是由一个非常古老的遗留系统生成的。
我的主要问题:如果 gunzip 可以做到......是否有一个调整或标志我忽略了提升它可以让它做呢?
失败的 C++ 代码看起来像这样(大大简化以专注于这一点,因此它可能包含语法错误):
#include <boost/iostreams/filtering_stream.hpp>
#include <boost/iostreams/copy.hpp>
#include <boost/iostreams/filter/gzip.hpp>
#include <sstream>
#include <iostream>
#include <fstream>
// Open File
ifstream file("myfile", ios::in|ios::binary);
int line = 1;
char c;
while (!file.eof() && line < 5){
// I do do 'way' more error checking and proper handling here
// in real code, but you get the point.. I'm moving the cursor
// past the last new line and the beginning of what is otherwise
// compressed content.
file.get(c);
if(c == '\n')line++;
}
stringstream ss;
// Store rest of binary data into stringstream
while(!file.eof()){
file.get(c);
ss.put(c);
}
// Close File
file.close();
// Return file pointer to potential gzip stream
ss.seekg(0, ios::beg);
try
{
stringstream gzipped(ss.str());
io::filtering_istream gunzip;
gunzip.push(io::gzip_decompressor());
gunzip.push(gzipped);
copy(gunzip, ss);
}
catch(io::gzip_error const& ex)
// always throws error code 4 here (bad_header)
cout << "Exception: " << ex.error() << endl;
以下是一些更有用的信息,可能会有所帮助:
- 操作系统:红帽 5.7
- 升压:boost-1.33.1-10(el5 存储库)
- 平台:x86_64
- GCC:版本 4.1.2 20080704(红帽 4.1.2-46)
我的 Makefile 在链接器中也有以下几行:
LDFLAGS = -lz -lboost_iostreams