使用Python读取大文件的方法
作者:DB乐之者 发布时间:2022-02-18 00:43:35
背景
最近处理文本文档时(文件约2GB大小),出现memoryError错误和文件读取太慢的问题,后来找到了两种比较快Large File Reading 的方法,本文将介绍这两种读取方法。
准备工作
我们谈到“文本处理”时,我们通常是指处理的内容。Python 将文本文件的内容读入可以操作的字符串变量非常容易。文件对象提供了三个“读”方法: .read()、.readline() 和 .readlines()。每种方法可以接受一个变量以限制每次读取的数据量,但它们通常不使用变量。 .read() 每次读取整个文件,它通常用于将文件内容放到一个字符串变量中。然而.read() 生成文件内容最直接的字符串表示,但对于连续的面向行的处理,它却是不必要的,并且如果文件大于可用内存,则不可能实现这种处理。下面是read()方法示例:
try:
f = open('/path/to/file', 'r')
print f.read()
finally:
if f:
f.close()
调用read()会一次性读取文件的全部内容,如果文件有10G,内存就爆了,所以,要保险起见,可以反复调用read(size)方法,每次最多读取size个字节的内容。另外,调用readline()可以每次读取一行内容,调用readlines()一次读取所有内容并按行返回list。因此,要根据需要决定怎么调用。
如果文件很小,read()一次性读取最方便;如果不能确定文件大小,反复调用read(size)
比较保险;如果是配置文件,调用readlines()最方便:
for line in f.readlines():
process(line) #分块读取
处理大文件是很容易想到的就是将大文件分割成若干小文件处理,处理完每个小文件后释放该部分内存。这里用了iter 和 yield:
def read_in_chunks(filePath, chunk_size=1024*1024):
"""
Lazy function (generator) to read a file piece by piece.
Default chunk size: 1M
You can set your own chunk size
"""
file_object = open(filePath)
while True:
chunk_data = file_object.read(chunk_size)
if not chunk_data:
break
yield chunk_data
if __name__ == "__main__":
filePath = './path/filename'
for chunk in read_in_chunks(filePath):
process(chunk) # <do something with chunk>
使用With open()
with语句打开和关闭文件,包括抛出一个内部块异常。for line in f文件对象f视为一个迭代器,会自动的采用缓冲IO和内存管理,所以你不必担心大文件。
代码如下:
#If the file is line based
with open(...) as f:
for line in f:
process(line) # <do something with line>
优化
面对百万行的大型数据使用with open 是没有问题的,但是这里面参数的不同也会导致不同的效率。经过测试发先参数为"rb"时的效率是"r"的6倍。由此可知二进制读取依然是最快的模式。
with open(filename,"rb") as f:
for fLine in f:
pass
测试结果:rb方式最快,100w行全遍历2.9秒。基本能满足中大型文件处理效率需求。如果从rb(二级制读取)读取改为r(读取模式),慢5-6倍。
结论
在使用python进行大文件读取时,应该让系统来处理,使用最简单的方式,交给解释器,就管好自己的工作就行了。同时根据不同的需求可以选择不同的读取参数进一步获得更高的性能。
来源:https://www.cnblogs.com/wenBlog/archive/2018/02/11/8441231.html
猜你喜欢
- 在网上查找大量资料,经过自己的不懈努力,终于测试成功了。原来要在服务器上安装mysql odbc 3.51 ,还有数据库用户名及密码,用下面
- 自定义模板403<!DOCTYPE html><html lang="en"><head&
- 有过Web经验的人喜欢使用:<meta http-equiv="refresh" content="1;
- Python语言功能非常强大,除了类之外,还有模块和包的概念,这有点像perl,此处简单说说包和模块。一、Python中的模块模块——其实就
- 这次让我们来看看一个真实场景吧:银行转账一、举例银行转账假设现在有一个xuewei的账号里面有 100W。然后有多个任务在转账,转入转出都是
- 一、简介urllib 库,它是 Python 内置的 HTTP 请求库,不需要额外安装即可使用,它包含四个模块:`request` 请求模块
- 插入一条记录后,如何得到最新的自动增加ID?我们要用到SQL Server的@@IDENTITY。它能够记录下系统最近使用的一个IDENTI
- 本文实例讲述了php tpl模板引擎定义与使用。分享给大家供大家参考,具体如下:tpl.php<?phpnamespace tpl;/
- javascript曾一度被认为是玩具型的语言,因为它太容易上手,而且,javascript曾一度担任为web站点“打杂”的职责。直到Aja
- 软件版本:apache:Apache 2.4.6 Win64 PHP:PHP 5.5 VC11 x64 Non Thr
- 直接给源代码了:$current_dir = 'E:/temp/';$dir = opendir($current_dir)
- asp数字分页涵数参数说明:SQL: 查询语句,PageSizeN: 每页显示多少新闻记录classid: 栏目ID,PageCountS:
- 在我们的日常生活工作中,经常会遇到需要上传日志的场景,比如多台机器运行同一个程序,并且需要记录每台机器程序产生的日志,根据相关关键词告警,或
- 关于opencvOpenCV 是 Intel 开源计算机视觉库 (Computer Version) 。它由一系列 C 函数和少量 C++
- 本次系统环境os: Deepin(Linux)Python: 3.7lib: PyYAML=5.3.1 | selenium=3.141.0
- 在Python中处理异常使用的是try-except代码块,try-except代码块放入让python执行的操作,同时告诉python程序
- 同事在准备新老系统的切换,清空一个表的时候往往发现这个表的主键被另一个表用做外键,而系统里有太多层次的引用.所以清起来相当麻烦用下面这个脚本
- 使用select @@identity 得到刚插入数据的ID1.适用于所有 ADO 版本<%Dim loConn, 
- 我们可以利用err对象来判断。当程序没有出现错误就说明已经执行了sql操作: sql="insert into
- 前言本文主要介绍了关于python中os和sys模块区别与常用方法的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧