Python大文件处理内存错误排查与低内存脚本优化咨询
问题分析与解决方案
我编写了一段Python脚本用于处理约64GB的超大文件
testinp.txt,同时读取25-30MB的testinpmap.txt。脚本看似按行读取大文件,但执行时内存占用极高,最终触发MemoryError。以下是我的代码:import re h_file_name="testinp.txt" #This file is very large approx 64GB size m_file_name="testinpmap.txt" #This files size is between 25-30MB with open(h_file_name, "rb") as f, open(h_file_name+".re.txt", "wb+") as f1, open(m_file_name,"rb") as f2: req="" s="" cols1 = [] for line in f: cols= re.split('[ ]+|[ ]+', line.strip()) for i in range(len(cols)): if str(cols[i]).strip() == "1": cols[i] = "2" cols1.append(cols) for line2 in f2: cols2 = re.split('[ ]+|[ ]+', line2.strip()) if (cols2[3].strip() != "."): for j in range(len(cols1[i])): if str(cols1[i][j]).strip() == "0": cols1[i][j] = "1" for c in cols1: req += " ".join(map(str,c)) req += "\n" f1.write(req)我疑惑为何按行读取仍会出现内存错误,且程序从执行开始就占用大量RAM,请问如何修改脚本以最小化内存占用并避免内存错误?
为什么你的脚本会爆内存?
核心问题是你没有真正做到“逐行处理后释放内存”,反而把所有数据都堆积在了内存里:
cols1列表会不断追加处理后的每一行数据,64GB的文件哪怕每行只有100字节,最终也会占用几十GB内存,直接触发MemoryError。req变量会累加所有处理后的行内容,最后一次性写入文件,这又会额外占用大量内存。- 更糟的是,你在处理大文件的每一行时,都会完整遍历一遍
testinpmap.txt(for line2 in f2),但文件指针读完一次后就会停在末尾,后续循环其实不会处理任何内容,还浪费了IO资源。 - 正则表达式
re.split('[ ]+|[ ]+')完全重复,简化成re.split(r'\s+')就可以(匹配任意空白字符)。
修改后的脚本(低内存版本)
我们的核心思路是:预加载小文件,逐行处理大文件,处理完一行就立刻写入输出文件,绝不把所有行存在内存里。
import re h_file_name = "testinp.txt" m_file_name = "testinpmap.txt" # 第一步:预加载并处理map文件(25-30MB完全可以存在内存) # 提取有效规则,避免重复读取文件 map_rules = [] with open(m_file_name, "rb") as f2: for line2 in f2: cols2 = re.split(r'\s+', line2.strip()) # 二进制模式下字符串是bytes类型,要用b""匹配 if cols2[3].strip() != b".": map_rules.append(cols2) # 第二步:逐行处理大文件,处理完立刻写入输出 with open(h_file_name, "rb") as f, open(h_file_name + ".re.txt", "wb") as f1: for line in f: # 第一步替换:把1改成2 cols = re.split(r'\s+', line.strip()) for i in range(len(cols)): if cols[i].strip() == b"1": cols[i] = b"2" # 第二步应用map规则(修正原逻辑中的cols1[i]笔误,改用当前行的cols) for cols2 in map_rules: for j in range(len(cols)): if cols[j].strip() == b"0": cols[j] = b"1" # 处理完立刻写入,不占用额外内存 processed_line = b" ".join(cols) + b"\n" f1.write(processed_line)
关键优化点说明
- 预加载小文件:把
testinpmap.txt的内容一次性加载到内存,避免在大文件的每行循环里重复读取,既节省IO资源,也减少重复加载的内存开销。 - 逐行处理+即时写入:处理大文件时,内存中只保留当前行的数据,处理完立刻写入输出文件,Python会自动回收这部分内存,内存占用会一直保持在很低的水平(仅当前行+map文件的内存)。
- 修正二进制字符串处理:因为你用了
rb/wb模式,所有字符串都是bytes类型,所以要用b"1"、b"2"这种格式,避免类型不匹配的错误(原代码里str(cols[i])会把bytes转成b'1'格式的字符串,这是错误的)。 - 移除内存堆积变量:删掉
cols1、req这些会累积数据的变量,从根源上避免内存溢出。
额外建议
- 如果map文件规则可以简化(比如只需要特定字段),预加载时只提取需要的部分,进一步减少
map_rules的内存占用。 - 可以用
line.split()(默认按任意空白分割)代替re.split,速度更快,内存占用更低。 - 若需要更高效的处理,可考虑用
pandas分块读取,但纯文本场景下,上面的逐行方法已经足够高效且内存友好。
内容的提问来源于stack exchange,提问作者user8393448
相关产品推荐
相关产品推荐

