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

时间:2017-03-19 17:22:38

标签: go compression file-format 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

我发现Go会接受该文件,如果我使用compress/lzw包压缩它,我只使用a website中的代码来执行此操作。我只修改了行

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

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

注意:file.txt为16.0 kB,unix-compressed file.txt.Z为7.8 kB,go-compressed 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。

3 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:0)

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

答案 2 :(得分:0)

此问题后面有一个古老的Bug,名为"alignment bit groups"。我已经在维基百科"Special output format"中对其进行了描述。请阅读。

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