背景:

使用 python 读取一个相对较大内存的文件,比如电脑运行内存只有1G,但是读取的文件大小为 2G,这个时候怎么处理呢?有人说直接用 open函数不就好了吗?但是如果你直接使用的话,会把文件一次性读取存在内存中,这个时候就会出现 OOM(内存溢出)即MemoryError,那么我们应该怎么处理呢?

我们先来看看python读取文件后,获取文件内容的几种方法;

方法作用
f.read()读取文件中所有内容
f.readline()读取第一行的内容
f.readlines()读取文件里面所有内容,把每行的内容放到一个list里面

从上面三种方法不难看出,第一种和第三种都会一次性读取完文件,这样文件如果足够大,都会将内存占满,如果要想解决上面的内存溢出问题,似乎第二种方法可以解决,但是这个方法的解释是读取第一行的内容,那么我们的文件其他内容怎么获取呢?

其实第二种方法还有补充说明,就是读取第一行的内容后,光标会移动到第一行末尾,下次调用该方法时,读取第二行内容,依次类推;

那就好办了,咱们直接撸代码;

def get_file_data_with_readline():
    with open('demo1.py', 'r', encoding='utf-8') as f:
        while True:
            data = f.readline()
            if data:
                print(data)
            else:
                return 

有木有高级一点的写法?好了,用生成器实现,接着撸!

def get_file_data_with_readline_generator():
    with open('demo1.py', 'r', encoding='utf-8') as f:
        while True:
            data = f.readline()
            if data:
                yield data
            else:
                return
  1. 这样子就通过每次读取每行的内容,把整个文件的内容输出了,也不会一次性将内存用完导致内存溢出;简直完美啊!!!,第三种方法也可以在方法中加入参数(即要指定读取的行数)那么实现效果和上面效果其实是一样的,每次从第一行依次读取到最后一行即可;

  2. 哈哈哈哈,你以为到这里就结束了吗?NoNoNo,我在字节二面的时候,面试官扔出来一个问题就是,那么如果存在某个文件某一行的内容超过了1G,怎么办?emmm~~~,小老弟难受不???

  3. 如果可以指定字符长度去读取就好了,上面的第一种方法其实也是支持传入参数的,可以支持传入读取的字符长度,这里其实就是考我知不知道这个细节,哎,之前没有研究所以当时没答上,其实注意这里就好了;

直接上代码:

def get_file_data_with_read_generator(size=10):
    with open('demo1.py', 'r', encoding='utf-8') as f:
        while True:
            data = f.read(size)
            if data:
                yield data
            else:
                return

这样就每次通过读取指定字符长度(默认长度为10)的内容,把整个文件输出了,over~~~

更多推荐

Python 优雅的读取大内存文件