我用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。它具有所有可能的选项:
--without-magic-header
(-w
) - 禁用魔术标头--max-code-bit-length
(-b
) - 设置最大代码位长度 (9-16)--raw
(-r
) - 禁用阻止模式--msb
(-m
) - 启用最高有效位--unaligned-bit-groups
(-u
) - 启用未对齐的位组
您可以使用所有可能组合中的任何选项。所有组合都已经过测试。我相信你可以找到适合 go lzw 实现的组合。
如果您喜欢使用红宝石,则可以使用 ruby-lzws 绑定。