Spring gzip_decompressor失败,Gunzip成功
boost gzip_decompressor failing where gunzip succeeds
我们的一个产品在工作中涉及一个具有以下结构的文件:
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。
毫无疑问,我正在处理的文件不是防弹的,是由一个非常古老的遗留系统生成的。
我的主要问题:如果枪手可以做到...有没有我用提升忽略的调整或标志也可以让它做到这一点?
失败的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 提升
- :提升-1.33.1-10(el5 存储库)
- 平台: x86_64 GCC:版本 4.1.2
- 20080704(红帽 4.1.2-46)
我的生成文件在链接器中也有以下行:
LDFLAGS = -lz -lboost_iostreams
我不确定这是否是您错误的根本原因,但是您对file.eof()
的使用不正确。 该函数仅在您尝试读取超过文件末尾后返回 true。 它不会通知您下一次读取是否会失败。
while(!file.eof()){ //1
file.get(c); // 2
ss.put(c); // 3
}
在此循环中,如果您读取第 2 行的最后一个有效字符,则在第 3 行输出它。 然后,它再次测试第 1 行上的条件。 由于您尚未尝试读取文件末尾,因此file.eof()
返回 false,因此循环条件为 true。 然后,它尝试读取下一个字符,但失败,c
保持不变。 然后,第 3 行将该无效字符放入ss
中。
这会导致流末尾出现一个额外的字符。 我不确定这是否是唯一的问题,但它可能是其中之一。
编辑:
好的,看完之后,我不是 100% 确定为什么会发生这种情况,但这是因为您正在重用字符串流ss
.在执行复制之前调用ss.seekp(0, ios::begin)
,或使用单独的字符串流。
就个人而言,与其将ss
复制到gzipped
,我会直接从输入文件写入gzipped
,然后通过复制到 ss。
- cmake在我的项目中所需的所有静态库都不成功
- 尽管测试成功,CppUnit测试核心仍被丢弃.为什么
- 如何让LLDB在成功时退出,在失败时等待
- 有没有办法知道Tracer是否成功地完全连接到了jaegerclientcpp中的jaeger后端服务器
- CMake WxWidgets项目成功地在Linux上构建,但没有在Windows上构建
- 为什么 std::绑定错误参数可以成功?
- Clion显示错误,但可以使用Cmake成功构建代码
- 代码使用向量成功运行,但使用数组显示错误
- 如何检查cURL是否成功登录?c ++
- 为什么 WinInet 在通过 FQDN 连接时无法通过协商自动进行身份验证,但如果通过 IP 连接则成功?
- C++为什么我的编译器成功了,但我的计算机给出了调试错误?
- 未知的 GCC 链接器错误,但已成功构建
- 我的 SonarQube C++扫描成功,但结果仅标记重复项,而没有标记其他标记的位置
- 为什么 LoadLibrary 失败,而 LoadLibraryA 成功加载 DLL?
- 生成成功,但不会给出正确的输出
- 默认/样板代码在Visual Studio 2017中给我错误.E1574.虚幻.但构建成功了
- 即使不包含其标头,如何成功向前声明的类编译?
- C++成功复制动态分配的 obj 而不复制 ctor?
- VS2017 版本 15.8.3 成功编译内联方法,而不返回所需值
- Spring gzip_decompressor失败,Gunzip成功