使用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实现批量修改文件名实例
Jul 08 Python
Python中Class类用法实例分析
Nov 12 Python
python对象及面向对象技术详解
Jul 19 Python
python如何定义带参数的装饰器
Mar 20 Python
django 解决manage.py migrate无效的问题
May 27 Python
解决python "No module named pip" 的问题
Oct 13 Python
Python之pymysql的使用小结
Jul 01 Python
关于初始种子自动选取的区域生长实例(python+opencv)
Jan 16 Python
jupyter 导入csv文件方式
Apr 21 Python
python用Configobj模块读取配置文件
Sep 26 Python
python 如何将两个实数矩阵合并为一个复数矩阵
May 19 Python
对Keras自带Loss Function的深入研究
May 25 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
php文件夹与文件目录操作函数介绍
2013/09/09 PHP
PHP下载文件函数与用法示例
2019/09/27 PHP
JavaScript经典效果集锦
2010/07/06 Javascript
jquery multiSelect 多选下拉框
2010/07/09 Javascript
jquery 跨域访问问题解决方法(笔记)
2011/06/08 Javascript
jquery 倒计时效果实现秒杀思路
2013/09/11 Javascript
代码触发js事件(click、change)示例应用
2013/12/13 Javascript
jquery 实现输入邮箱时自动补全下拉提示功能
2015/10/04 Javascript
Jquery easyui 实现动态树
2015/11/17 Javascript
js实现的奥运倒计时时钟效果代码
2015/12/09 Javascript
AngularJS通过$location获取及改变当前页面的URL
2016/09/23 Javascript
JavaScript基本类型值-Number类型
2017/02/24 Javascript
利用jQuery实现一个简单的表格上下翻页效果
2017/03/14 Javascript
Web制作验证码功能实例代码
2017/06/19 Javascript
BootStrap TreeView使用实例详解
2017/11/01 Javascript
Vuejs+vue-router打包+Nginx配置的实例
2018/09/20 Javascript
新手入门带你学习JavaScript引擎运行原理
2019/06/24 Javascript
详解基于原生JS验证表单组件xy-form
2019/08/20 Javascript
解决nuxt 自定义全局方法,全局属性,全局变量的问题
2020/11/05 Javascript
python创建和使用字典实例详解
2013/11/01 Python
wxPython窗口中文乱码解决方法
2014/10/11 Python
浅谈插入排序算法在Python程序中的实现及简单改进
2016/05/04 Python
Python基于递归算法实现的汉诺塔与Fibonacci数列示例
2018/04/18 Python
Python csv模块使用方法代码实例
2019/08/29 Python
使用python实现数组、链表、队列、栈的方法
2019/12/20 Python
Python正则re模块使用步骤及原理解析
2020/08/18 Python
HTML5所有标签汇总及标签意义解释
2015/03/12 HTML / CSS
6PM官网:折扣鞋、服装及配饰
2018/08/03 全球购物
波兰快递服务:Globkurier.pl
2019/11/08 全球购物
机电一体化自荐信
2013/12/10 职场文书
《蓝色的树叶》教学反思
2014/02/24 职场文书
《金孔雀轻轻跳》教学反思
2014/04/20 职场文书
公司自我介绍演讲稿
2014/08/21 职场文书
2014年妇幼卫生工作总结
2014/12/09 职场文书
SpringBoot整合Mybatis Generator自动生成代码
2021/08/23 Java/Android
MyBatis 动态SQL全面详解
2021/10/05 MySQL