如何使用包含额外数据的 Gzip 文件?

2024-04-02

我正在编写一个脚本,它将以 gzip 流的形式处理来自仪器的数据。在大约 90% 的情况下,gzip模块工作完美,但某些流导致它产生IOError: Not a gzipped file。如果 gzip 标头被删除并且 deflate 流直接馈送到zlib,我反而得到Error -3 while decompressing data: incorrect header check。经过大约半天的头撞墙后,我发现有问题的流末尾附加了看似随机数量的额外字节(不是 gzip 数据的一部分)。

让我感到奇怪的是,Python 无法使用这些文件有两个原因:

  1. Gzip 和 7zip 都可以毫无问题地打开这些“填充”文件。 (Gzip 产生消息decompression OK, trailing garbage ignored,7zip 默默地成功了。)
  2. Gzip 和 Python 文档似乎都表明这应该有效:(强调我的)

    Gzip的格式.txt http://www.gzip.org/format.txt:

    一定可以 使用任何压缩方法检测压缩数据的结尾, 无论压缩数据的实际大小如何。尤其, 解压缩器必须能够检测并跳过附加的额外数据 到有效的压缩文件在面向记录的文件系统上,或者当 压缩数据只能从设备中读取 一定的块大小。

    Python 的 gzip.GzipFile` http://docs.python.org/library/gzip.html#gzip.GzipFile:

    呼叫一个GzipFile对象的close()方法没有关闭fileobj, 因为您可能希望在压缩数据后附加更多材料。这也允许您通过StringIO打开对象以写入为fileobj,并使用检索结果内存缓冲区StringIO对象的getvalue() method.

    蟒蛇的zlib.Decompress.unused_data http://docs.python.org/library/zlib.html#zlib.Decompress.unused_data:

    包含压缩数据末尾之后的任何字节的字符串。也就是说,这仍然是""直到包含压缩数据的最后一个字节可用。如果整个字符串包含压缩数据,则这是"",空字符串。

    确定压缩数据字符串结束位置的唯一方法是实际解压缩它。这意味着当压缩数据包含在较大文件的一部分时,您只能通过以下方式找到它的结尾读取数据并将其后跟一些非空字符串输入解压对象的decompress()方法直到unused_data属性不再是空字符串。

这是我尝试过的四种方法。 (这些示例是 Python 3.1,但我测试了 2.5 和 2.7,也遇到了同样的问题。)

# approach 1 - gzip.open
with gzip.open(filename) as datafile:
    data = datafile.read()

# approach 2 - gzip.GzipFile
with open(filename, "rb") as gzipfile:
    with gzip.GzipFile(fileobj=gzipfile) as datafile:
        data = datafile.read()

# approach 3 - zlib.decompress
with open(filename, "rb") as gzipfile:
    data = zlib.decompress(gzipfile.read()[10:])

# approach 4 - zlib.decompressobj
with open(filename, "rb") as gzipfile:
    decompressor = zlib.decompressobj()
    data = decompressor.decompress(gzipfile.read()[10:])

难道我做错了什么?

UPDATE

好吧,虽然问题是gzip似乎是模块中的错误,我的zlib问题都是自己造成的。 ;-)

在深入挖掘的同时gzip.py我意识到我做错了什么——默认情况下,zlib.decompress等人。期望 zlib 包装的流,而不是裸露的 deflate 流。通过传递负值wbits,你可以告诉zlib跳过 zlib 标头并解压缩原始流。这两者都有效:

# approach 5 - zlib.decompress with negative wbits
with open(filename, "rb") as gzipfile:
    data = zlib.decompress(gzipfile.read()[10:], -zlib.MAX_WBITS)

# approach 6 - zlib.decompressobj with negative wbits
with open(filename, "rb") as gzipfile:
    decompressor = zlib.decompressobj(-zlib.MAX_WBITS)
    data = decompressor.decompress(gzipfile.read()[10:])

这是一个错误。 Python 中的 gzip 模块的质量远远低于 Python 标准库应要求的质量。

这里的问题是 gzip 模块假设该文件是 gzip 格式文件的流。在压缩数据的末尾,它从头开始,期待一个新的 gzip header;如果找不到,则会引发异常。这是错误的。

当然,它is有效连接两个 gzip 文件,例如:

echo testing > test.txt
gzip test.txt
cat test.txt.gz test.txt.gz > test2.txt.gz
zcat test2.txt.gz
# testing
# testing

gzip 模块的错误是,如果第二次没有 gzip 标头,它不应该引发异常;它应该简单地结束文件。它应该only如果第一次没有标题,则引发异常。

如果不直接修改 gzip 模块,就没有干净的解决方法;如果你想这样做,请查看底部_read方法。它应该设置另一个标志,例如。reading_second_block, 告诉_read_gzip_header募集EOFError代替IOError.

该模块还存在其他错误。例如,它进行不必要的查找,导致它在不可查找的流(例如网络套接字)上失败。这让我对这个模块信心不足:如果开发人员不知道 gzip 需要在没有搜索的情况下运行,那么他就根本没有资格为 Python 标准库实现它。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用包含额外数据的 Gzip 文件? 的相关文章

  • Mac OS 上的诗歌安装失败,显示“should_use_symlinks”

    我正在尝试使用以下命令安装诗歌 curl sSL https install python poetry org python3 但它失败了 但有以下例外 例外 此版本的 python 无法在不使用符号链接的情况下创建 venvs 下面是详
  • 使用 matplotlib 从“列表列表”绘制 3D 曲面

    我已经搜索了一些 虽然我可以找到许多有用的网格网格示例 但没有一个清楚地表明我如何将列表列表中的数据转换为可接受的形式 以适应我所讨论的各种方式 当谈到 numpy matplotlib 以及我所看到的建议的术语和步骤顺序时 我有点迷失 我
  • 如何在Python中流式传输和操作大数据文件

    我有一个相对较大 1 GB 的文本文件 我想通过跨类别求和来减小其大小 Geography AgeGroup Gender Race Count County1 1 M 1 12 County1 2 M 1 3 County1 2 M 2
  • 使用 pygame 显示 unicode 符号

    我检查了其他答案 但不明白为什么我的代码错误地显示 This is what I currently see https i stack imgur com 8tNIK png 这是关于文本渲染的相关代码 font pygame font
  • 补丁 - 为什么相对补丁目标名称不起作用?

    我已经从模块导入了一个类 但是当我尝试修补类名而不使用模块作为前缀时 出现类型错误 TypeError Need a valid target to patch You supplied MyClass 例如 以下代码给出了上述错误 imp
  • 如何检查python xlrd库中的excel文件是否有效

    有什么办法与xlrd库来检查您使用的文件是否是有效的 Excel 文件 我知道还有其他库可以检查文件头 我可以使用文件扩展名检查 但为了多平台性我想知道是否有任何我可以使用的功能xlrd库本身在尝试打开文件时可能会返回类似 false 的内
  • Kivy - 有所有颜色名称的列表吗?

    在 Kivy 中 小部件 color属性允许输入其值作为字符串颜色名称 也 例如在 kv file Label color red 是否有所有可能的颜色名称的列表 就在这里 来自Kivy 的文档 https kivy org doc sta
  • 检查 Python 中的可迭代对象中的所有元素的谓词是否计算为 true

    我很确定有一个常见的习语 但我无法通过谷歌搜索找到它 这是我想做的 用Java Applies the predicate to all elements of the iterable and returns true if all ev
  • pyspark 数据框中的自定义排序

    是否有推荐的方法在 pyspark 中实现分类数据的自定义排序 我理想地寻找 pandas 分类数据类型提供的功能 因此 给定一个数据集Speed列 可能的选项是 Super Fast Fast Medium Slow 我想实现适合上下文的
  • 搜索多个字段

    我想我没有正确理解 django haystack 我有一个包含多个字段的数据模型 我希望搜索其中两个字段 class UserProfile models Model user models ForeignKey User unique
  • Keras:如何保存模型或权重?

    如果这个问题看起来很简单 我很抱歉 但是阅读 Keras 保存和恢复帮助页面 https www tensorflow org beta tutorials keras save and restore models https www t
  • 一段时间后终止线程的最 Pythonic 方法

    我想在线程中运行一个进程 它正在迭代一个大型数据库表 当线程运行时 我只想让程序等待 如果该线程花费的时间超过 30 秒 我想终止该线程并执行其他操作 通过终止线程 我的意思是我希望它停止活动并优雅地释放资源 我认为最好的方法是通过Thre
  • Django 的 request.FILES 出现 UnicodeDecodeError

    我在视图调用中有以下代码 def view request body u for filename f in request FILES items body body Filename filename n f read n 在某些情况下
  • 在 Windows 上使用 apache mod_wsgi 运行 Flask 应用程序时导入冲突

    我允许您询问我在 Windows 上使用您的 mod wsgi portage 托管 Flask 应用程序时遇到的问题 我有两个烧瓶应用程序 由于导入冲突 只有一个可以同时存在 IE 如果请求申请 1 我有回复 然后 如果我请求应用程序 2
  • 使用 python 绘制正值小提琴图

    我发现小提琴图信息丰富且有用 我使用 python 库 seaborn 然而 当应用于正值时 它们几乎总是在低端显示负值 我发现这确实具有误导性 尤其是在处理现实数据集时 在seaborn的官方文档中https seaborn pydata
  • 使用 Keras np_utils.to_categorical 的问题

    我正在尝试将整数的 one hot 向量数组制作为 keras 将能够使用的 one hot 向量数组来拟合我的模型 这是代码的相关部分 Y train np hstack np asarray dataframe output vecto
  • 将seaborn.palplot轴添加到现有图形中以可视化不同调色板

    将seaborn人物添加到子图中是usually https seaborn pydata org examples cubehelix palette html创建图形时通过传递 ax 来完成 例如 sns kdeplot x y cma
  • 在 keras 中保存和加载权重

    我试图从我训练过的模型中保存和加载权重 我用来保存模型的代码是 TensorBoard log dir output model fit generator image a b gen batch size steps per epoch
  • 在 Django 查询中使用 .extra(select={...}) 引入的值上使用 .aggregate() ?

    我正在尝试计算玩家每周玩游戏的次数 如下所示 player game objects extra select week WEEK games game date aggregate count Count week 但姜戈抱怨说 Fiel
  • 多个对象以某种方式相互干扰[原始版本]

    我有一个神经网络 NN 当应用于单个数据集时 它可以完美地工作 但是 如果我想在一组数据上运行神经网络 然后创建一个新的神经网络实例以在不同的数据集 甚至再次同一组数据 上运行 那么新实例将产生完全错误的预测 例如 对 XOR 模式进行训练

随机推荐