Python:从文件中读取数据,有时压缩,有时不压缩
我需要从一些通常用gzip压缩的文件中读取二进制数据。我已使用gzip模块成功读取数据: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
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