前言 在日常的测试开发工作中,需要经常对文件进行处理,如对日志文件的分析,对数据文件的遍历,如果遇到比较大的文件,那就要求程序的健壮性有更高的要求。 实例 1、现以读取
前言
在日常的测试开发工作中,需要经常对文件进行处理,如对日志文件的分析,对数据文件的遍历,如果遇到比较大的文件,那就要求程序的健壮性有更高的要求。
实例
1、现以读取一个大小为900M的文件为例,现已常用的文件处理方式把每行内容打印出来,并记录处理时间。
start=time.time()with open("/Users/xxx/Downloads/绝命毒师.mp4", "rb") as fp:
print(fp.read())
end=time.time()
eplase=end-start
print(eplase)
运行结果:
(打印内容省略)...
...
...
230.72680592536926
解析:
运行程序可以看到,Pycharm的控制台也是等了差不多60S后才有显示的内容,这是因为程序要先把文件所有内容读取放入内存中,然后再对文件的内容做逐行打印,整个处理时间花费了230S,如果文件更大的话这种处理逻辑还有可能报内存溢出的错误。
优化:
为防止内存溢出的异常场景出现,对上述处理逻辑进行优化改进,不再将所有内容一次性读取,而是每次读取固定大小内容,直至文件读取完毕。
start=time.time()f = open("/Users/xxx/Downloads/绝命毒师.mp4", 'rb')
while True:
block = f.read(2048)
print(block)
if not block:
break
f.close()
end=time.time()
eplase=end-start
print(eplase)
解析:
运行程序可以看到,控制台实时打印每次读取的内容,且整体运行时间为 36.65S,效率得到了大大的提升。读取更大容量的文件也没问题。
2、利用生成器函数也是读取大容量文件的利器之一
def read_file(fpath):BLOCK_SIZE = 2048
with open(fpath, 'rb') as f:
while True:
block = f.read(BLOCK_SIZE)
if block:
yield block
else:
return "over"
start = time.time()
a = read_file("/Users/xxx/Downloads/绝命毒师.mp4")
for i in a:
print(i)
end=time.time()
eplase=end-start
print(eplase)
运行结果:
(打印内容省略)...
...
...
35.480741024017334
解析:
可以看到,运行程序控制台也是实时打印每次读取的内容,且整体运行时间为 35.48S,效率和每次固定读取内容的方法大致相同。
去期待陌生,去拥抱惊喜。