C++压缩库

15

我正在阅读有关程序压缩的内容,并开始创建一个新的简单项目,一个压缩器(只是一个压缩器,不是解压器),但我只找到了zLib,而且它是为C语言设计的。 我知道C库可以在C++中使用,但我更喜欢使用C++库。 有人知道可以推荐的好的库吗?

最好的问候。


5
如果你使用 C++ 编译器来编译 C 库,通常它会正常工作(然后变成 C++ 库)。 - Carl Norum
3
如果您要创建一个不能解压缩的压缩实用程序,那么有什么比“rm BIG_FILE”更好的选择呢? - Mark Rushakoff
可能吗?不仅可能……它一定会起作用。 - sean riley
@Carl 这是个好主意。@Mark 哈哈 - Nathan Campos
看起来我应该把那个作为答案,否则我会错过声望! - Carl Norum
如果您使用C编译器编译库,那么您可以将其链接到C++代码中,而且这个过程基本上是透明的。但是,是的,您也可以使用C++编译器来编译它。 - MarkR
7个回答

12

10

我所知道的大多数压缩库都是用C编写的,原因有两个:一是因为好的压缩算法普遍历史较长;二是因为C在各个平台上具有高度的可移植性(和稳定性)。

我建议使用以下任何一个。如果你想要良好的许可证,请选择前两个之一,否则,如果你愿意使用GPL代码,选择最后两个之一。


2
我建议使用zlib。它是为C设计的,但在C++中也可以正常工作。
当库足够大且复杂以至于可以从面向对象设计中受益时,使用本地C ++库确实有所帮助。zlib相对简单,不需要面向对象的特性。

2

我已经检查了libzip的源代码,感觉有点糟糕。我不知道是否错过了某个变量设置,但是src.stat_error在整个zip_open()方法中都有未定义的值;而且src.stat_error在比较中被使用了两次。除此之外,它多次初始化变量,有时甚至在使用变量之前就初始化了。有大量的function_pointer调用。有些function_pointer的使用感觉很愚蠢,函数调用感觉循环性质,尽管实际上并非如此。而且libzip在zip_open方法中进行了所有的分配;这是浪费的,因为我只想枚举文件。 - undefined
就像libzip从来不需要一次性进行所有的分配一样。它可以简单地分配一个索引表,列举出zip文件的所有元素;然后在稍后分配和提取所需的数据。更好的做法是,当用户稍后枚举出成员时,立即将其添加到索引表中。libzip将会有一个额外的get_next_entry()函数。而zip_stat_index则是在我只需要一条信息时浪费处理器时间和内存的。 - undefined
最后,我仔细研究了代码,试图解密libzip是如何获取中央目录结束标头的。起初我感到兴奋,但后来我意识到,试图从文件前面找到中央目录结束标志必然会导致错误。那时候我已经太累了,无法进一步分析代码。 - undefined
可惜的是,ZIP文件格式设计得不够好。如果你从前往后读,本地头部不一定存在,你遇到的本地头部可能是悬空的;而且在搜索ECOD签名时,压缩数据中可能包含该签名。反向读取ZIP文件时,ECOD注释出现在注释长度之前。因此,你不能只是跳过长度注释,然后再跳过22个字节找到ECOD签名。 - undefined
我看到三种可能的解决方案。1. 寻找 clamp(file_length-65578,0) SEEK_SET。读取4个字节并将它们与 ECOD 标志进行比较。然后验证其余的 ECOD 成员。根据维基百科,由于 ECOD 标志着 zip 文件的结尾,所以注释位置 + 注释长度应该是文件的结尾。如果注释长度不是65546个字符,会浪费一些时间。2. 转到文件末尾 - 22。将字节存储在一个25字节的数组中。在第一次迭代中,只比较前4个字节。如果失败,再向后寻找22个字节。将字节1-3移动到数组中的索引22处。复制22个字节到数组中。比较整个数组。重复此过程,直到找到 ECOD 标志为止。 - undefined
最后的方法是因为注释标记了zip文件的结尾...需要一个22字节的缓冲区。从文件末尾向前定位到-22位置。复制字节并向后检查,直到字符不是ASCII可打印字符为止。如果失败,则向后定位22个字节,并进行检查,直到文件的开头也失败为止。如果找到了非可打印字符,则获取uint16并检查长度是否偏移到文件的末尾。 - undefined

2

Zlib很好,但您可能还想查看LZMA SDK(您可以压缩为.7z格式,除了zip)。


1

这似乎完美而轻松,谢谢。 - Aidan

1

强烈推荐使用zlib。它编写得很好,接口相当清晰。我不认为C++包装器能够简化API多少。此外,在我看来,zlib在(解)压缩速度和文件大小之间取得了良好的平衡。Bzip2要慢得多,而LZO和UCL的压缩比更差。


Zlib 接口对我来说有点奇怪。我更喜欢 boost::iostreams 的封装,更加合理。 - piotr
Zlib仍然局限于Deflate压缩方法吗?如果是的话,我能使用Deflate方法来打开任何zip归档条目吗? - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接