python - 为什么使用 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)
这是之前和之后的文件。
那么,我做错了什么?
解决方案
永远不能期望或依赖解压缩和重新压缩会产生相同的结果。不同的压缩代码、相同代码的不同版本或不同的压缩设置都会产生不同的结果。无损压缩器提供的唯一保证是相反的顺序,即,如果您先压缩然后解压缩,您将得到最初的结果。
就您而言,问题是是什么使它“对游戏不可读”。
更新给定的二进制文件:
之前和之后的 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')
)
推荐阅读
- json - 使用fromMap在flutter中映射来自firebase文档的嵌套对象
- apache-spark - 使用 PySpark 组合 Spark 模式而不重复?
- python - Pandas Slice Columns 并根据条件选择子集
- antlr3 - Antlr4 中的 Antr3 规则重写
- c# - 如何使用 UnitTest 在 IList C# 中添加多个项目
- networking - 无法 SSH 或 PING RasPi3B+ IP 地址
- php - 在 WooCommerce 4+ 中发送自定义电子邮件通知的多个自定义订单状态
- php - 如何让 PHP 显示错误而不是给我 500 Internal Server Error NGINX + PHP7
- javascript - 当我尝试在 Firefox 上的 webextension 插件设置页面上保存设置时,出现“上下文不活动时已解决的承诺”错误
- python - 海龟子类不画直线