Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/358.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/python-2.7/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python:从文件中读取数据,有时压缩,有时不压缩_Python_Python 2.7_Gzip - Fatal编程技术网

Python:从文件中读取数据,有时压缩,有时不压缩

Python:从文件中读取数据,有时压缩,有时不压缩,python,python-2.7,gzip,Python,Python 2.7,Gzip,我需要从一些通常用gzip压缩的文件中读取二进制数据。我已使用gzip模块成功读取数据: def decode(self, filename): with gzip.open(filename, 'rb') as f: # ReadData 然而,有时文件没有被压缩,在这种情况下,我会得到一个IOError(因为文件没有gzip头) 我可以这样做: try: f = gzip.open(filename, 'rb') f._read_gzip_heade

我需要从一些通常用gzip压缩的文件中读取二进制数据。我已使用gzip模块成功读取数据:

def decode(self, filename):
    with gzip.open(filename, 'rb') as f:
        # ReadData
然而,有时文件没有被压缩,在这种情况下,我会得到一个IOError(因为文件没有gzip头)

我可以这样做:

try:
    f = gzip.open(filename, 'rb')
    f._read_gzip_header()
    f.rewind()
except IOError:
    f.close()
    f = open(filename, 'rb')

with f as gz:
    #ReadData
但我觉得这不是解决问题的好办法

我正在寻找一个优雅的解决方案来解决这个问题。我将为几种文件类型编写几个“解码”函数。我考虑的解决方案是创建GZIP文件的子类来处理它,但我相信可能有更好的方法。 我正在使用Python 2.7


提前感谢您的建议

您可以检查前两个字节是否为
\x1f
\x8b
,如下所示:

成员标题和尾部

ID1(标识1)ID2(标识2) 这些文件具有固定值ID1=31(0x1f\037),ID2=139(0x8b\213),以标识文件为gzip格式

那么比如说,

with open('test.gz','rb') as f:
    print(f.read(2))

b'\x1f\x8b' #well, that was gzipped

with open('test','rb') as f:
    print(f.read(2))

b'he' #must not be gzipped
假设您将基于这两个字节执行一些控制流,然后
f.seek(0)
并相应地继续


但老实说?您的解决方案很好(将不必要的关闭/重新打开部分进行模块化)
try/except
是pythonic。

您的解决方案有什么问题?我不会先关闭文件,然后立即重新打开它,但使用try/except处理潜在的
IOError
是完全正确的。只要试着把它读成gzip,除了
IOError
读成纯文本,除了
IOError
traceback。然后干净利落地进行所有处理,处理代码不知道文件是如何打开的。好吧,也许我的解决方案没有什么问题(我对Python不是很有经验,有时我怀疑什么是好的/错的)。我之所以不喜欢我的解决方案,是因为我将编写至少6个解码函数(针对6种不同的文件类型),我认为可能有更好的方法可以避免在每个函数中编写try-except块。但是感谢您的评论。如果问题是您不想复制代码,那么只需创建一个新的contextmanager,它将生成一个类似文件的对象,其中包含未压缩的数据,无论输入是否压缩。谢谢你的回答。(我对两位炼金术士的评论也适用于此)。但是我不明白我的代码的哪一部分是不必要的:如果我不使用“with”语句打开文件,我不需要使用close()吗?是的,如果不使用with语句作为上下文管理器,您应该尝试手动显式关闭文件对象。然而,背对背地写
f.close
然后
打开(相同的文件)
就像关闭然后重新打开一扇门一样毫无意义:P