Python gzip.open().read()的大小参数

Python gzip.open().read()的大小参数,python,gzip,Python,Gzip,在Python中使用gzip库时,我经常会遇到使用.read()函数的代码,其模式如下: with gzip.open(filename) as bytestream: bytestream.read(16) buf = bytestream.read( IMAGE_SIZE * IMAGE_SIZE * num_images * NUM_CHANNELS ) data = np.frombuffer(buf, dtype=np.uint8).a

在Python中使用
gzip
库时,我经常会遇到使用
.read()
函数的代码,其模式如下:

with gzip.open(filename) as bytestream:
    bytestream.read(16) 
    buf = bytestream.read(
        IMAGE_SIZE * IMAGE_SIZE * num_images * NUM_CHANNELS
    )
    data = np.frombuffer(buf, dtype=np.uint8).astype(np.float32)
虽然我熟悉上下文管理器模式,但我很难真正理解
with
上下文管理器中的第一行代码到底在做什么

这是
read()
函数的文档:

从流中读取最多n个字符

从底层缓冲区读取,直到有n个字符或达到EOF。 如果n为负或省略,则读取直到EOF

如果是这种情况,那么第一行
bytestream.read(16)
的功能角色必须是读取,从而跳过前16个字符,可能是因为它们充当元数据或标头。但是,当我有一些图像时,我怎么知道使用
16
作为
read
调用的参数,而不是说32或8或64

我记得有很多次遇到与上面完全相同的代码,除了让作者使用
bytestream.read(8)
而不是
bytestream.read(16)
或者其他任何值。一个字符一个字符地深入到文件中,没有可识别的模式来确定头字符的长度

换句话说,如何确定要在
读取
函数调用中使用的参数?
或者如何知道gzip压缩文件中头字符的长度

我猜测这与字节有关,但在搜索文档和在线参考资料后,我无法确认这一点

可复制的细节 我的假设是,经过无数个小时的故障排除,前16个字符代表某种类型的标题或元数据。因此,该代码的第一行是跳过16个字符,并将剩余的字符存储在名为
buf
的变量中。然而,深入研究数据,我发现没有办法确定为什么或如何选择值16。我已经一个字符一个字符地读取了字节,也尝试了读取并将它们转换为
np.float
,但是没有明显的模式表明元数据在第16个字符处结束,而实际数据在第17个字符处开始

下面的代码从中读取数据并提取前30个字符。请注意,标题行“结束”(显然是第16行,在第二次出现\x1c`之后)和数据开始的位置是不可分辨的:

import gzip
import numpy as np

train_data_filename = 'data_input/train-images-idx3-ubyte.gz'
IMAGE_SIZE = 28
NUM_CHANNELS = 1

def extract_data(filename, num_images):
    with gzip.open(filename) as bytestream:
        first30 = bytestream.read(30)
        return first30

first30= extract_data(train_data_filename, 10)
print(first30)
# returns: b'\x00\x00\x08\x03\x00\x00\xea`\x00\x00\x00\x1c\x00\x00\x00\x1c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
如果我们修改代码将它们转换为
np.float32
,这样所有字符现在都是数字(float),那么同样没有明显的模式来区分头/元数据的结束和数据的开始


任何参考或建议将不胜感激

从代码片段中,
bytestream.read(16)
读取或跳过bytestream的前16个字节。当您引用read()从流中最多读取n个字符时,它会这样做,但python似乎在1个字节中存储一个字符,使16个字符占用16个字节

请参阅有关字符和字节的更多信息

代码片段主要关注buf的内容,跳过流的前16个字节。要了解如何确定首先进入
bytestream.read()的参数
AKA确定要跳过压缩图像文件的多少字节,我们必须了解其余代码的作用。特别是,我们正在读取什么文件,以及使用numpy(?)库(将rgb图像保存在1D numpy阵列中)尝试实现什么


我肯定不是图像处理方面的专家,但似乎
bytestream.read(16)
是处理某些独特压缩图像文件的独特问题的独特解决方案。因此,如果不看到更多代码和理解代码片段背后的更多逻辑,就很难判断如何确定要跳过多少字节。

从gzip的角度来看,它返回给您的一切都是数据。该数据流中没有元数据或gzip特定的头内容,因此不需要任何算法来计算gzip向该数据流中预加了多少内容:它预加的字节数为零


向下滚动至链接页面的底部;MNIST数据库有一个标题为“文件格式”的标题

该格式规范确切地告诉您格式是什么,以及每个头使用了多少字节。具体而言,每个文件中的前四项描述如下:

0000 32位整数0x0000083(2051)幻数
0004 32位整数60000个图像
0008 32位整数28行数
0012 32位整数28列数

因此,如果您想跳过所有四个项目,您可以从顶部减去16个字节。

它只是指定缓冲区大小。请参见:这是非常特定于单个数据格式的。编写代码的人大概对他们正在解析的内容有足够的了解,从而可以在手边做出假设。您的问题没有指定代码要解析的数据格式的任何内容,而代码的需求完全由该格式的规范驱动,因此。。。这应该如何回答呢?只有很小一部分格式(如JSON、s表达式或msgpack)承载模式——在大多数情况下,包含哪些字段位于哪些偏移量&c的详细信息。他们不在乐队里。如果幸运的话,有一个正式的规范文档,或者类似protobuf规范的东西,可以用来自动生成机器解析器。。。但是这些东西是否存在,我们甚至不能告诉你从哪里开始,除非你能从描述其格式的数据作者那里找到文档