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



我用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 会接受该文件,我只是使用了这样做的网站的代码。我只修改了行

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

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

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

现在,我试图理解为什么会发生这种情况。所以,我试着跑

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 文件不等效?我怎样才能克服这个问题?

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

A .Z 文件不仅包含 LZW 压缩数据,还有一个 Go LZW 代码不会生成的 3 字节标头,因为它旨在压缩数据,而不是生成 Z 文件。

大概你只想测试你/一些第三方算法(而不是压缩算法本身)的性能,你可能想写一个shell脚本,它调用压缩命令传递所需的文件/目录,然后从你的C/GO程序调用这个脚本。这是克服此问题的一种方法,但会打开查询的其他部分,以正确使用压缩库

这个问题背后有一个名为"对齐位组"的古老错误。我在维基百科中描述了它的"特殊输出格式"。请阅读。

我已经实现了一个新的库 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-lzws 绑定。

相关内容

最新更新