【发布时间】:2023-06-21 22:29:01
【问题描述】:
我一直试图通过修改 zpipe.c 示例在 zlib 中设置字典。即,我有一个包含 32768 个字符的文件,我想将其转换为字典。所以我修改了zpipe(http://www.zlib.net/zpipe.c)。
在 def() 函数上,我补充说:
char dict[32768];
FILE *fd = fopen("dictB.txt", "r");
ssize_t test = fread(dict, 32768, 1, fd);
int lenDict = (int) sizeof(dict);
fclose(fd);
在 deflateInit() 之后,我添加了以下内容
ret = deflateSetDictionary(&strm, (const Bytef*) dict, lenDict);
为了更好的衡量,我在调用 deflate() 之前添加了 deflateSetDictionary 和每个点
在 inf() 函数上,我添加了相同的字典(为了完整性而重复):
char dict[32768];
FILE *fd = fopen("dictB.txt", "r");
ssize_t test = fread(dict, 32768, 1, fd);
int lenDict = (int) sizeof(dict);
fclose(fd);
在 inflate() 调用之后,我修改了 zpipe.c 使其可以接受字典调用:
ret = inflate(&strm, Z_NO_FLUSH);
if (ret==Z_NEED_DICT){
ret = inflateSetDictionary(&strm, (const Bytef*) dict, lenDict);
}
assert(ret != Z_STREAM_ERROR); /* state not clobbered */
switch (ret) {
case Z_DATA_ERROR:
case Z_MEM_ERROR:
(void)inflateEnd(&strm);
return ret;
}
现在,运行压缩后
$ ./zpipe < file.txt > file.gz
然后一切正常运行
但是当我尝试解压时
$ ./zpipe -d < file.gz > file.dec.txt
然后我得到一个与Z_DATA_ERROR相关的错误:
zpipe: invalid or incomplete deflate data
执行 deflateSetDictionary 调用时不会出现此错误。我知道这个错误与 deflateSetDictionary 有关,并且可能在使用缓冲区实现时,因为在使用字典运行其他示例时没有错误(例如http://www.chuntey.com/Source/Zlib/example.c)
【问题讨论】:
-
这是什么意思:“为了更好的衡量,我在调用 deflate() 之前添加了 deflateSetDictionary 和每个点”?
deflateSetDictionary只能调用一次,紧跟在deflateInit之后。 -
这一行的实例:'int lenDict = (int) sizeof(dict);'这将始终返回 32768,无论 dict[] 数组的内容如何
-
@MarkAdler,我一开始也是这么想的,但后来手册说:“使用 zlib 格式时,必须在 deflateInit、deflateInit2 或 deflateReset 之后以及任何 deflate 调用之前立即调用此函数.",其中最后一部分的措辞我觉得有些不清楚。我最初也尝试过只打一次电话,但紧随 deflateInit... 会再试一次。
-
@user3629249,字典的字节数也是32768,但是你说得对,我需要修改为strlen()
-
在
inflateSetDictionary()之后,您需要再次运行inflate()。否则你会掉出内部循环并覆盖已读取的输入。
标签: c dictionary compression zlib deflate