使用Python读取大文件的方法


Posted in Python onFebruary 11, 2018

背景

最近处理文本文档时(文件约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进行大文件读取时,应该让系统来处理,使用最简单的方式,交给解释器,就管好自己的工作就行了。同时根据不同的需求可以选择不同的读取参数进一步获得更高的性能。

Python 相关文章推荐
python采用getopt解析命令行输入参数实例
Sep 30 Python
Python中用pycurl监控http响应时间脚本分享
Feb 02 Python
python3 图片referer防盗链的实现方法
Mar 12 Python
python pyheatmap包绘制热力图
Nov 09 Python
Python图像的增强处理操作示例【基于ImageEnhance类】
Jan 03 Python
python 格式化输出百分号的方法
Jan 20 Python
python 如何将数据写入本地txt文本文件的实现方法
Sep 11 Python
Python打包工具PyInstaller的安装与pycharm配置支持PyInstaller详细方法
Feb 27 Python
Python json模块与jsonpath模块区别详解
Mar 05 Python
使用OpenCV获取图片连通域数量,并用不同颜色标记函
Jun 04 Python
Pycharm安装Qt Design快捷工具的详细教程
Nov 18 Python
Python+Selenium实现读取网易邮箱验证码
Mar 13 Python
python脚本作为Windows服务启动代码详解
Feb 11 #Python
分析Python读取文件时的路径问题
Feb 11 #Python
Django中针对基于类的视图添加csrf_exempt实例代码
Feb 11 #Python
python jieba分词并统计词频后输出结果到Excel和txt文档方法
Feb 11 #Python
代码讲解Python对Windows服务进行监控
Feb 11 #Python
django 按时间范围查询数据库实例代码
Feb 11 #Python
python实现媒体播放器功能
Feb 11 #Python
You might like
不用数据库的多用户文件自由上传投票系统(3)
2006/10/09 PHP
PHP程序漏洞产生的原因分析与防范方法说明
2014/03/06 PHP
CodeIgniter连贯操作的底层原理分析
2016/05/17 PHP
php防止sql注入的方法详解
2017/02/20 PHP
PHP addcslashes()函数讲解
2019/02/03 PHP
一个简单的jQuery插件制作 学习过程及实例
2010/04/25 Javascript
EasyUI的treegrid组件动态加载数据问题的解决办法
2011/12/11 Javascript
JavaScript的Module模式编程深入分析
2013/08/13 Javascript
JQuery中对Select的option项的添加、删除、取值
2013/08/25 Javascript
Javascript 拖拽的一些简单的应用(逐行分析代码,让你轻松了拖拽的原理)
2015/01/23 Javascript
JavaScript通过prototype给对象定义属性用法实例
2015/03/23 Javascript
jQuery Validate插件实现表单验证
2016/08/19 Javascript
详解js中Json的语法与格式
2016/11/22 Javascript
vue写一个组件
2018/04/09 Javascript
微信小程序实现美团菜单
2018/06/06 Javascript
express+vue+mongodb+session 实现注册登录功能
2018/12/06 Javascript
Angular中innerHTML标签的样式不起作用的原因解析
2019/06/18 Javascript
JS实现页面鼠标点击出现图片特效
2020/08/19 Javascript
JavaScript数组常用的增删改查与其他属性详解
2020/10/13 Javascript
js面向对象封装级联下拉菜单列表的实现步骤
2021/02/08 Javascript
html5以及jQuery实现本地图片上传前的预览代码实例讲解
2021/03/01 jQuery
vue+flask实现视频合成功能(拖拽上传)
2021/03/04 Vue.js
浅谈python迭代器
2017/11/08 Python
python实现朴素贝叶斯分类器
2018/03/28 Python
Python迭代器与生成器用法实例分析
2018/07/09 Python
Python实现繁体中文与简体中文相互转换的方法示例
2018/12/18 Python
Etam艾格英国官网:法国著名女装品牌
2019/04/15 全球购物
校园门卫岗位职责
2013/12/09 职场文书
抗洪救灾先进集体事迹材料
2014/05/26 职场文书
群众路线教育实践活动的心得体会
2014/09/03 职场文书
区域经理岗位职责
2015/02/02 职场文书
家长对孩子的寄语
2015/02/26 职场文书
工地食品安全责任书
2015/05/09 职场文书
PyCharm配置KBEngine快速处理代码提示冲突、配置命令问题
2021/04/03 Python
Java面试题冲刺第十五天--设计模式
2021/08/07 面试题
golang生成并解析JSON
2022/04/14 Golang