背景:
使用 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
-
这样子就通过每次读取每行的内容,把整个文件的内容输出了,也不会一次性将内存用完导致内存溢出;简直完美啊!!!,第三种方法也可以在方法中加入参数(即要指定读取的行数)那么实现效果和上面效果其实是一样的,每次从第一行依次读取到最后一行即可;
-
哈哈哈哈,你以为到这里就结束了吗?NoNoNo,我在字节二面的时候,面试官扔出来一个问题就是,那么如果存在某个文件某一行的内容超过了
1G
,怎么办?emmm~~~,小老弟难受不??? -
如果可以指定字符长度去读取就好了,上面的第一种方法其实也是支持传入参数的,可以支持传入读取的字符长度,这里其实就是考我知不知道这个细节,哎,之前没有研究所以当时没答上,其实注意这里就好了;
直接上代码:
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~~~