c - 使用 C 的 Zlib 和 Gzip:不正确的标头检查 (Z_DATA_ERROR)
问题描述
我正在从此处下载 .txt.gz 格式的图形数据集。下载后我尝试使用 zlib 解压缩它。我使用的代码大部分是从zpipe.c
示例中抄袭的,对使用gzopen
、gzfread
和gzclose
、Z_SYNC_FLUSH
加号进行了更改inflateInit2(&stream, (32 + MAX_WBITS))
。我也试过(16 + MAX_WBITS)。
如标题中所述,我收到的错误消息是Z_DATA_ERROR (-3)
“不正确的标头检查”。
现在可以使用 zcat(和 zless)打开数据,并且标题似乎也可以:
1F 8B gzip
08 deflate
00 no special information
33 0c 36 59 last modification
00 no extra flags
03 unix
简而言之,我不知道有什么问题。
下面是我使用的代码。
int uncompress_dataset(const char* gz_path, const char* out_path) {
int ret;
unsigned have;
z_stream stream;
FILE* out_file;
gzFile in_gz_file;
unsigned char in[CHUNK];
unsigned char out[CHUNK];
int err_no = 0;
const char* emsg;
stream.zalloc = Z_NULL;
stream.zfree = Z_NULL;
stream.opaque = Z_NULL;
stream.avail_in = 0;
stream.next_in = Z_NULL;
ret = inflateInit2(&stream, (32 + MAX_WBITS));
if (ret != Z_OK) {
zlib_error(ret);
return -1;
}
out_file = fopen(out_path, "wb");
in_gz_file = gzopen(gz_path, "rb");
if (out_file == NULL) {
printf("%s", "couldn't open the output file");
inflateEnd(&stream);
return -1;
}
if (in_gz_file == NULL) {
printf("%s", "couldn't open the input file as gzip");
fclose(out_file);
inflateEnd(&stream);
return -1;
}
do {
stream.avail_in = gzfread(in, 1, CHUNK, in_gz_file);
if (stream.avail_in == 0) {
emsg = gzerror(in_gz_file, &err_no);
if (err_no < 0 || err_no == 2) {
printf("Error when reading %s", emsg);
zlib_error(err_no);
inflateEnd(&stream);
fclose(out_file);
gzclose(in_gz_file);
return -1;
} else {
break;
}
}
stream.next_in = in;
do {
stream.avail_out = CHUNK;
stream.next_out = out;
ret = inflate(&stream, Z_SYNC_FLUSH);
printf("Return value of inflate: %i\n", ret);
assert(ret != Z_STREAM_ERROR);
switch (ret) {
case Z_NEED_DICT:
ret = Z_DATA_ERROR;
case Z_DATA_ERROR:
case Z_MEM_ERROR:
printf("Error: %s\n", stream.msg);
inflateEnd(&stream);
zlib_error(ret);
fclose(out_file);
gzclose(in_gz_file);
return -1;
}
have = CHUNK - stream.avail_out;
if (fwrite(out, 1, have, out_file) != have || ferror(out_file)) {
inflateEnd(&stream);
zlib_error(ret);
fclose(out_file);
gzclose(in_gz_file);
return -1;
}
} while (stream.avail_out == 0);
} while (ret != Z_STREAM_END);
fclose(out_file);
gzclose(in_gz_file);
inflateEnd(&stream);
return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
}
解决方案
推荐阅读
- php - 如何使用php eval()或round()只显示小数点后的两个数字?
- ios - Youtube iOS 播放器问题 (youtube-ios-player-helper)
- php - 基于Laravel中数组的值和总和来区分数组
- javascript - 就 JavaScript 引擎而言,实现原型委托而不是基于类的继承是否有好处?
- swift - 编程 UITextField 在 viewDidLoad 上不可见
- php - SQLSTATE [42S22]:未找到列:1054 Laravel 中“字段列表”中的未知列“会话”
- arrays - 拖放阵列 AS3
- javascript - javascript根据标题数量将数组复制到新数组中
- c - Valgrind 错误与其他信任中的动态结构数组
- php - 我无法为我的画廊图像获取模态框