在python中逐行读取一个大的压缩文本文件

Posted

技术标签:

【中文标题】在python中逐行读取一个大的压缩文本文件【英文标题】:Read a large zipped text file line by line in python 【发布时间】:2012-07-14 00:05:52 【问题描述】:

我正在尝试使用 zipfile 模块来读取存档中的文件。未压缩文件约为 3GB,压缩文件为 200MB。我不希望它们在内存中,因为我逐行处理压缩文件。到目前为止,我注意到使用以下代码的内存过度使用:

import zipfile
f = open(...)
z = zipfile.ZipFile(f)
for line in zipfile.open(...).readlines()
  print line

我是在 C# 中使用 SharpZipLib 完成的:

var fStream = File.OpenRead("...");
var unzipper = new ICSharpCode.SharpZipLib.Zip.ZipFile(fStream);
var dataStream =  unzipper.GetInputStream(0);

dataStream 未压缩。我似乎找不到在 Python 中做到这一点的方法。我们将不胜感激。

【问题讨论】:

【参考方案1】:

Python 文件对象提供迭代器,它将逐行读取。 file.readlines() 将它们全部读取并返回一个列表 - 这意味着它需要将所有内容读入内存。更好的方法(应该始终优先于readlines())是只循环对象本身,例如:

import zipfile
with zipfile.ZipFile(...) as z:
    with z.open(...) as f:
        for line in f:
            print line

注意我对the with statement 的使用——文件对象是上下文管理器,with 语句让我们可以轻松编写可读代码,确保在退出块时(即使出现异常)关闭文件。同样,在处理文件时应该始终使用它。

【讨论】:

不能说比这更好了 @Gareth Latty,是否有关于 open 函数采用什么类型的参数的说明文档?我想看看我是否可以像使用“with open()”函数一样为 open() 设置内存缓冲区 我注意到的另一件事是z.open() 似乎不允许r 选项。当您需要在 for line in f: 块中运行一些逻辑时,这就会发挥作用。 示例: if line.find("YES") != -1: print('yay')。这将返回 TypeError。您必须在"YES" 前面加上b 才能使其工作。 @ericOnline 那是因为你得到的是字节,而不是 unicode 字符串。根据用例,您可能希望将其解码为 UTF-8 以获取真正的字符串,而不仅仅是使用字节字符串。 使用 io.TextIOWrapper;例如with io.TextIOWrapper(z.open(...), encoding='utf-8') as f:

以上是关于在python中逐行读取一个大的压缩文本文件的主要内容,如果未能解决你的问题,请参考以下文章

在python中逐行迭代一个大的.xz文件

如何在 html 文本区域中逐行读取文本? [复制]

在一个非常大的文件中逐行读取特定的行

如何读取用 7z 压缩的文本文件?

用python从符合一定格式的txt文档中逐行读取数据并按一定规则写入excel(openpyxl支持Excel 2007 .xlsx格式)

在 Swift 中逐行读取文本文件?