3分钟学会,学会用Python正确读取大文件

3分钟学会,学会用Python正确读取大文件

文件读写属于一种常见的IO操做,因为操做系统将底层操做磁盘的接口向上封装为一种通用接口,所以Python中读写文件的基本方法和JAVA、PHP等高级编程语言同样,先请求操做系统打开一个文件描述符,经过操做系统提供的接口从这个文件对象中读取数据,或者把数据写入这个文件中,最后当文件读写操做完成后关闭文件。python

须要注意的是文件读写完成后必须及时关闭文件,一方面打开的文件会占用操做系统的资源,而且操做系统同一时间能打开的文件数量也是有限制的,好比Linux操做系统中咱们可使用ulimit -n命令查看最多可打开文件的数量。另外一方面在写文件时,操做系统是把数据放到内存缓冲区异步写入磁盘中,并不会马上把数据所有写入磁盘,而调用close()方法可使操做系统把没有写入磁盘的数据所有写入磁盘中,防止数据丢失的状况。接下来咱们先看下正确的文件打开方式。编程

文件打开的几种方式缓存

Python内置了open()方法打开了一个文件,以下所示。文件打开模式有'r'、'w'、'a'、'r+'、'w+'、'a+'、'b'等,'r'只读模式打开文件,并将文件指针指向文件头,若是文件不存在会报错;'w'只写模式打开文件,并将文件指针指向文件头,若是文件存在则将其内容清空,不存在则建立;'a'以只追加可写模式打开文件,并将文件指针指向文件尾部,若是文件不存在则建立。对应于open()方法打开文件须要有close()方法关闭文件。异步

f = open('/mnt/media/log.txt', 'r')
f.read()
f.close()

因为读写文件时都有可能产生IOError,好比文件不存在的状况,此时open()方法会抛出一个IOError的异常,那么后面的f.close()就不会被调用。为了保证不管是否出错都能正确地关闭文件,咱们可使用try ... finally来实现。编程语言

try:
 f = open('/mnt/media/log.txt', 'r')
 f.read()
finally:
 if f:
 f.close()

因为try ... finally方式实现较为繁琐,Python引入了with语句会自动调用f.close()方法,使得代码更简洁。ide

with open('/mnt/media/log.txt', 'r') as f:
 f.read()

大文件读取几种方式工具

对文件的读取操做是将文件中的数据加载到内存中,那么对于大文件的读取,若是一次把文件中所有的内容所有加载到内存中显然会耗尽系统的内容。咱们看下Python中读取文件经常使用的方法read()、readline()、readlines()对于大文件读取的支持状况:read(size)方法是从文件当前位置起读取size个字节,若无参数size,则表示读取至文件结束为止,若是文件比较小,用read()一次读取文件较为方便,但若是不能肯定文件大小,反复调用read(size)比较保险;readline()方法每次读出一行内容,因此读取时占用内存小,比较适合大文件。readlines()方法读取整个文件全部行,保存在一个列表list变量中,每行做为一个元素,读取大文件时比较占内存。学习

说到大文件的读取,有个linecache模块,这里要说明下的是这个模块的优点是经过缓存文件内容的方式来加快下次读取文件的速度,因此须要耗费更多的内存,那么如下是我在Linux发行版LEDE+MT7688的环境下对readlines、linecache.getlines以及遍历文件这三种方式在内存的使用状况下的对比:开发工具

在学习过程当中有什么不懂得能够加个人
python学习交流扣扣qun,784-758-214
群里有不错的学习视频教程、开发工具与电子书籍。
与你分享python企业当下人才需求及怎么从零基础学习好python,和学习什么内容
count = len(open(filepath, 'r').readlines())
_________________________________________________________
count = = len(linecache.getline(filepath) )
_________________________________________________________
count = 0
for count, line in enumerate(open(filepath,'r')):
 pass
count += 1
________________________________________________
count = len([ "" for line in open("filename","r")])
不打开文件:Mem: 37648K used, 88184K free, 116K shrd, 0K buff, 12540K cached 
readlines读取文件:Mem: 69560K used, 56272K free, 124K shrd, 0K buff, 27004K cached 
linecache.getlines读取文件:Mem: 70396K used, 55436K free, 116K shrd, 0K buff, 26996K cached
遍历方式读取文件:Mem: 53032K used, 72800K free, 116K shrd, 0K buff, 27668K cached

可是linecache.getlines在读取文件的速度上是有绝对优点的,由于文件内容已经缓存在内存中了,下次读取能够直接从内存中获取,可使用linecache.checkcache检测文件在磁盘上是否发生了变化,若是变化了须要使用linecache.updatecache更新缓存。不过首次读取文件须要打开文件,对于一个15M左右20000行的日志文件三种方式差很少须要八、9秒的时间,但第二次读取文件linecache.getlines方式是微秒级的。操作系统

readlines读取文件:

time count 215794 type1 is 9.58759188652

time count 215794 type1 is 1.70862102509

time count 215794 type1 is 2.05462002754

time count 215794 type1 is 1.69754505157

time count 215813 type1 is 2.1633579731

time count 215813 type1 is 1.61879992485

遍历方式读取文件:

time count 215508 type2 is 8.8404238224

time count 215508 type3 is 2.22844409943

time count 215508 type2 is 2.19772100449

time count 215508 type3 is 2.57516384125

time count 215586 type2 is 2.12095785141

time count 215586 type3 is 2.55960321426

time count 215586 type2 is 2.1704659462

time count 215586 type3 is 2.11596107483

linecache.getlines读取文件:

time count 214811 type4 is 8.19337201118

time count 214811 type4 is 6.50882720947e-05

time count 214811 type4 is 9.41753387451e-05

time count 214811 type4 is 6.69956207275e-05

time count 214811 type4 is 9.41753387451e-05

time count 214811 type4 is 6.89029693604e-05

以为文章还能够的话不妨收藏起来慢慢看,有任何意见或者见解欢迎你们评论!

相关文章
相关标签/搜索