with open(filename, "rb") as f:
- f.read() 读取整个文件,通常将文件内容放到一个字符串变量中;
- f.readline() 次读取一行内容;
- f.readlines() 一次性读取所有内容并按行返回list;
当读取的文件较大时,全部读取内存中,会导致内存溢出
第一种:readline()
def md5_sum(filename):
with open(filename, "rb") as f:
f.seek(0)
line = f.readline()
md5 = hashlib.md5()
md5.update(line)
while line:
line = f.readline()
md5.update(line)
f_md5 = md5.hexdigest()
print(f_md5)
return f_md5
我以一个1.4G的文件进行测试
4dcafe2e69d6d0a8979cb4eb7c26c3fd
耗时: 6.345685958862305
Current memory usage is 0.008476MB; Peak was 5.260233MB
耗时 6s,峰值内存占用5.2M
第二种:readlines()
def md5_sum2(filename):
with open(filename, "rb") as f:
f.seek(0)
md5 = hashlib.md5()
for line in f.readlines():
md5.update(line)
f_md5 = md5.hexdigest()
print(f_md5)
return f_md5
一次性将文件读到内存中,如果内存不够会报错
4dcafe2e69d6d0a8979cb4eb7c26c3fd
耗时: 7.258216857910156
Current memory usage is 0.008476MB; Peak was 1654.899472MB
耗时 7.2s,峰值内存占用1654M
反而速度更慢!
第三种:read()
def md5_sum3(filename):
def chunked_file_reader(file, block_size=1024 * 16):
"""生成器函数:分块读取文件内容,使用 iter 函数
"""
# 首先使用 partial(fp.read, block_size) 构造一个新的无需参数的函数
# 循环将不断返回 fp.read(block_size) 调用结果,直到其为 '' 时终止
for chunk in iter(partial(file.read, block_size), b''):
yield chunk
with open(filename, "rb") as f:
f.seek(0)
md5 = hashlib.md5()
for line in chunked_file_reader(f):
md5.update(line)
f_md5 = md5.hexdigest()
print(f_md5)
return f_md5
利用read block_size读取大小限制,构造生成器
4dcafe2e69d6d0a8979cb4eb7c26c3fd
耗时: 3.0910959243774414
Current memory usage is 0.014733MB; Peak was 0.053139MB
耗时 3,峰值内存占用0.05M
第四种:read() + itertools
def md5_sum4(filename):
buffer = 1024 * 1024
with open(filename, "rb") as f:
buf_gen = takewhile(lambda x: x, (f.read(buffer) for _ in repeat(None)))
md5 = hashlib.md5()
for line in buf_gen:
md5.update(line)
f_md5 = md5.hexdigest()
print(f_md5)
return f_md5
itertools 有更好的for loop 性能
这里切片大小设置为 1024*1024
4dcafe2e69d6d0a8979cb4eb7c26c3fd
耗时: 2.7328171730041504
Current memory usage is 0.00074MB; Peak was 2.103334MB
耗时 2.7s,峰值内存占用2.1M
总结
- 后端分片的话可以考虑多线程,多进程的处理方案
- 但是一般业务场景 更多是前端上传的文件流的形式
- 更好的方案是前端拆分大文件,后端在接受文件的同时算出md5
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/48884.html