使用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 相关文章推荐
高性能web服务器框架Tornado简单实现restful接口及开发实例
Jul 16 Python
python使用分治法实现求解最大值的方法
May 12 Python
python使用wmi模块获取windows下硬盘信息的方法
May 15 Python
简单介绍Python中的readline()方法的使用
May 24 Python
Python编程中的文件操作攻略
Oct 16 Python
Python操作SQLite数据库的方法详解
Jun 16 Python
基于Python和Scikit-Learn的机器学习探索
Oct 16 Python
详解Python之unittest单元测试代码
Jan 24 Python
基于python实现名片管理系统
Nov 30 Python
解决pyinstaller打包pyqt5的问题
Jan 08 Python
Pytorch 实现变量类型转换
May 17 Python
Python GUI编程之tkinter 关于 ttkbootstrap 的使用详解
Mar 03 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 Session变量不能传送到下一页的解决方法
2009/11/27 PHP
PHP安全防范技巧分享
2011/11/03 PHP
Laravel中使用自己编写类库的3种方法
2015/02/10 PHP
关于PHP 如何用 curl 读取 HTTP chunked 数据
2016/02/26 PHP
Thinkphp框架使用list_to_tree 实现无限级分类列出所有节点示例
2020/04/04 PHP
JavaScript在多浏览器下for循环的使用方法
2012/11/07 Javascript
浅谈javascript构造函数与实例化对象
2015/06/22 Javascript
理解JavaScript表单的基础知识
2016/01/25 Javascript
javascript动态获取登录时间和在线时长
2016/02/25 Javascript
解析微信JS-SDK配置授权,实现分享接口
2016/12/09 Javascript
浅谈vuex 闲置状态重置方案
2018/01/04 Javascript
解决vuecli3.0热更新失效的问题
2018/09/19 Javascript
JavaScript学习笔记之基于定时器实现图片无缝滚动功能详解
2019/01/09 Javascript
微信小程序登录session的使用
2019/03/17 Javascript
vue实现PC端分辨率适配操作
2020/08/03 Javascript
JavaScript中Object、map、weakmap的区别分析
2020/12/15 Javascript
Python实现的飞速中文网小说下载脚本
2015/04/23 Python
python中global用法实例分析
2015/04/30 Python
在Python中操作字典之setdefault()方法的使用
2015/05/21 Python
Python实现快速多线程ping的方法
2015/07/15 Python
点球小游戏python脚本
2018/05/22 Python
python 发送和接收ActiveMQ消息的实例
2019/01/30 Python
Flask之pipenv虚拟环境的实现
2019/11/26 Python
pyftplib中文乱码问题解决方案
2020/01/11 Python
在django中使用post方法时,需要增加csrftoken的例子
2020/03/13 Python
关于python3.9安装wordcloud出错的问题及解决办法
2020/11/02 Python
html5嵌入内容_动力节点Java学院整理
2017/07/07 HTML / CSS
Python中pass语句的作用是什么
2016/06/01 面试题
小学二年级学生评语
2014/04/21 职场文书
社区维稳工作方案
2014/06/06 职场文书
法定代表人授权委托书范文
2014/09/22 职场文书
对照四风自我剖析材料
2014/10/07 职场文书
党员志愿者服务倡议书
2015/04/29 职场文书
运动会口号霸气押韵
2015/12/24 职场文书
2016中学教师读书心得体会
2016/01/13 职场文书
Java实现扫雷游戏详细代码讲解
2022/05/25 Java/Android