如何使用Python读取1个8GB大小的文件,这个问题其实在笔试中会常常遇到的1个题目。对于在Python中读取文件的操做,通常咱们会这样来操做:python
f = open('filename','rb') f.read()
下面咱们来找1个比较大的文件,好比1个nginx的日志文件,记得以前有一次公司的1天的nginx日志文件解压为3GB大小,不得不对其进行切分。nginx
这里咱们找到了1个3G大小的文件。接下来,咱们使用普通的读取方式来查看该文件的内容:缓存
f=open('test','rb') data=f.read() --------------------------------------------------------------------------- MemoryError Traceback (most recent call last) ... MemoryError:
咱们能够看到1个MemoryError的错误,说明该无文件没法被装载在内存中发生溢出了。
下面咱们来思考下为何内存会溢出了,在咱们打开文件的时候并无发生任何异常,而在咱们调用read方法时才出现问题。咱们知道,文件对象的read方法会尝试将全部内容以1行的形式读入,显然这种方式对于大文件是不可行的。函数
在Python中,除了使用read方法读取文件内容外,还有另外2个方法readline和readlines也能够进行内容的读取。
既然默认read方法是一次性的将内容都读取到内存中,那么咱们是否能够指定其每次读取的长度来解决这个问题呢?日志
data = f.read(1024) while 1: #处理该行的代码 data = f.read(1024)
而readlines会返回每1行读取的内容的列表,所以有必定风险的。code
for l in f.readlines(): #处理这1行的代码
那么,咱们每次读取1行总能够了把。这样咱们能够经过以下的方式来进行:对象
line = f.readline() while 1: #处理该行的代码 line = f.readline()
咱们经过1个无限循环的方式来进行读取。结果发现,使用readlines的方式仍是会致使内存不足的状况发生,而经过读取指定字节的方式则能够处理完这个文件。
在上面的解决方案中,咱们须要手动处理文件读取的大小,并在合适的状况退出读取的操做。
那么,咱们有没有更好的解决方案呢?其实是有的,在Python的手册中,有1个xreadlines的方法,这个方法就类比range和xrange函数的区别。这个方法返回相似iter(f)
的字符串,可是遗憾的是该方法在Python版本2.3中已经被淘汰了,官方建议咱们使用for语句来替代:内存
for line in f: #处理该行的代码
经过这种方式,Python将处理文件对象为1个迭代器,并自动使用缓存IO和内存管理,这样咱们就不须要关注大的文件了。 字符串
参考文件:get
http://stackoverflow.com/questions/8009882/how-to-read-large-file-line-by-line-in-python