为什么使用 unix-compress 和 go compress/lzw 产生不同的文件,其他解码器无法读取?

Why using unix-compress and go compress/lzw produce different files, not readable by the other decoder?

我在终端中使用 compress file.txt 压缩了一个文件并得到了(如预期的那样)file.txt.Z

当我将该文件传递给 Go 中的 ioutil.ReadFile 时,

buf0, err := ioutil.ReadFile("file.txt.Z")

我得到错误(上面的行是 116):

finder_test.go:116: lzw: invalid code

我发现如果我使用 compress/lzw 包压缩它,Go 会接受该文件,我只是使用 a website 中的代码来做到这一点。我只修改了行

outputFile, err := os.Create("file.txt.lzw")

我将 .lzw 更改为 .Z。然后在顶部的 Go 代码中使用生成的 file.txt.Z,它工作正常,没有错误。

注:file.txt为16.0kB,unix压缩file.txt.Z为7.8kB,go-compressedfile.txt.Z为8.2kB

现在,我正试图理解为什么会这样。所以,我尝试 运行

uncompress.real file.txt.Z

它没有用。我得到了

file.txt.Z: not in compressed format

我需要使用压缩器(最好是unix-compress)来压缩使用lzw-compression的文件,然后在两种不同的算法上使用相同的压缩文件,一种用C编写,另一种用Go编写,因为我打算比较这两种算法的性能。 C 程序只接受用 unix-compress 压缩的文件,Go 程序只接受用 Go 的 compress/lzw.

压缩的文件

有人可以解释为什么会这样吗?为什么这两个 .Z 文件不相同?我该如何克服这个问题?

注意:我正在 Ubuntu 安装在 Mac 上的 VirtualBox 中。

.Z文件不仅包含LZW压缩数据,还有a 3-bytes header Go LZW代码不会生成,因为它是为了压缩数据,而不是生成Z文件。

假设您只想测试两个 your/some 第三方算法的性能(而不是压缩算法本身),您可能想编写一个 shell 调用压缩命令的脚本传递 files/dir 的要求,然后从您的 C/GO 程序中调用此脚本。这是您可以克服这个问题的一种方法,但在使用压缩库的正确方法上留下查询的其他部分。

有一个名为 "alignment bit groups" behind this question. I've described it in wikipedia "Special output format" 的古老 bug。请阅读。

我实现了一个新库 lzws。它具有所有可能的选项:

  1. --without-magic-header (-w) - 禁用魔术头
  2. --max-code-bit-length (-b) - 设置最大码位长度 (9-16)
  3. --raw (-r) - 禁用块模式
  4. --msb (-m) - 启用最高有效位
  5. --unaligned-bit-groups (-u) - 启用未对齐的位组

您可以在所有可能的组合中使用任何选项。所有组合都经过测试。我相信您可以找到适合 go lzw 实现的组合。

喜欢ruby的可以使用ruby-lzws绑定。