【问题标题】:How do I automatically handle decompression when reading a file in Python?在 Python 中读取文件时如何自动处理解压缩?
【发布时间】:2013-08-24 10:05:14
【问题描述】:

我正在编写一些 Python 代码,它遍历多个文件并处理每个文件的前几百行。我想扩展此代码,以便如果列表中的任何文件被压缩,它会在读取它们时自动解压缩,以便我的代码始终接收解压缩的行。基本上我的代码目前看起来像:

for f in files:
    handle = open(f)
    process_file_contents(handle)

是否有任何函数可以替换上述代码中的open,这样如果f 是纯文本或gzip 压缩文本(或bzip2 等),该函数将始终返回一个文件句柄到解压后的文件内容? (无需查找,只需顺序访问。)

【问题讨论】:

  • 这不是重复的。我知道如何使用gzip.open。我本质上是在问是否有一个函数可以查看文件并自动选择opengzip.open,或者任何其他适合正在使用的压缩的打开函数,所以我不必写一堆尝试/catch 语句自己尝试所有可能的打开函数。
  • 类似this?

标签: python python-2.7 file-io compression


【解决方案1】:

我遇到了同样的问题:我希望我的代码接受文件名并返回一个文件句柄以用于with、自动压缩等。

就我而言,我愿意信任文件扩展名,我只需要处理 gzip 和 bzip 文件。

import gzip
import bz2

def open_by_suffix(filename):
    if filename.endswith('.gz'):
        return gzip.open(filename, 'rb')
    elif filename.endswith('.bz2'):
        return bz2.BZ2file(filename, 'r')
    else:
        return open(filename, 'r')

如果我们不信任文件名,我们可以比较文件的初始字节以获得魔术字符串(修改自 https://stackoverflow.com/a/13044946/117714):

import gzip
import bz2

magic_dict = {
    "\x1f\x8b\x08": (gzip.open, 'rb')
    "\x42\x5a\x68": (bz2.BZ2File, 'r')
}
max_len = max(len(x) for x in magic_dict)

def open_by_magic(filename):
    with open(filename) as f:
        file_start = f.read(max_len)
    for magic, (fn, flag) in magic_dict.items():
        if file_start.startswith(magic):
            return fn(filename, flag)
    return open(filename, 'r')

用法:

# cat
for filename in filenames:
    with open_by_suffix(filename) as f:
        for line in f:
            print f

您的用例如下所示:

for f in files:
    with open_by_suffix(f) as handle:
        process_file_contents(handle)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-01-12
    • 2021-06-19
    • 1970-01-01
    • 2012-06-21
    • 1970-01-01
    • 2020-05-26
    • 1970-01-01
    相关资源
    最近更新 更多