首页 > 解决方案 > 为什么使用 gzip 重新压缩文件会产生不同的输出?

问题描述

我需要解压缩、编辑然后重新压缩一个 Minecraft .dat 文件。然而,在重新压缩后,文件发生了显着变化(我没有进行任何编辑),这使得游戏无法读取。

这是我用来解压缩的代码片段,

import gzip
import shutil
with gzip.open('file_1.dat', 'rb') as f_in:
    with open('file_1.txt', 'wb') as f_out:
        shutil.copyfileobj(f_in, f_out)

这是我用来压缩文件的代码:

with open('file_1.txt', 'rb') as f_in2:
    with gzip.open('file_1_recmp.dat', 'wb') as f_out2:
        shutil.copyfileobj(f_in2, f_out2)

这是之前和之后的文件

那么,我做错了什么?

标签: pythoncompressiongzip

解决方案


永远不能期望或依赖解压缩和重新压缩会产生相同的结果。不同的压缩代码、相同代码的不同版本或不同的压缩设置都会产生不同的结果。无损压缩器提供的唯一保证是相反的顺序,即,如果您先压缩然后解压缩,您将得到最初的结果。

就您而言,问题是是什么使它“对游戏不可读”。

更新给定的二进制文件:

之前和之后的 gzip 文件都是有效的,并且具有相同的未压缩数据。

before 和 after 的主要区别在于 after 的 header 在 header 中有一个文件名和一些其他信息。我的第一个理论是游戏中的解压缩器不符合标准 gzip 标头,并且正在做一些简单和错误的事情,例如跳过前十个字节,期望接下来是 deflate 压缩数据。

您可以使用gzip.GzipFile代替gzip.open来控制标题的内容,将文件名留空。您还可以将修改时间设置为零,就像在原始标题中一样。简单的例子:

import sys
import gzip
f = open('out.gz', 'wb')
gz = gzip.GzipFile('', 'wb', 9, f, 0.)
gz.write('this is a test')
gz.close()
f.close()

(或者对于 Python 3,。gz.write(b'this is a test')


推荐阅读