在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从符合一定格式的txt文档中逐行读取数据并按一定规则写入excel(openpyxl支持Excel 2007 .xlsx格式)