替换大型txt文件中的字符串时绕过内存错误

时间:2019-10-08 12:11:41

标签: python

我要遍历几个文件,其中一些文件长达几百万行。一个文件可以超过500 MB。我需要通过搜索并将'| |'字符串替换为'|'字符串来准备它们。但是,以下代码遇到“内存错误”。如何重新编写代码以按行搜索和替换文件以节省RAM?有任何想法吗? 这并不是要逐行读取大文件,而是要逐行替换字符串,避免将列表转换为字符串,反之亦然。

import os
didi = self.lineEdit.text()
for filename in os.listdir(didi):            
    if filename.endswith(".txt"):
        filepath = os.path.join(didi, filename)
        with open(filepath, errors='ignore') as file:
            s = file.read()
            s = s.replace('| |', '|')
        with open(filepath, "w") as file:
               file.write(s)

2 个答案:

答案 0 :(得分:3)

尝试以下代码:

chunk_size = 5000
buffer = ""
i = 0

with open(fileoutpath, 'a') as fout:
    with open(fileinpath, 'r') as fin:
        for line in fin:
            buffer += line.replace('| |', '|')
            i+=1
            if i == chunk_size:
                    fout.write(buffer)
                    i=0
                    buffer = ""
    if buffer:
        fout.write(buffer)
        i=0
        buffer = ""

此代码一次在内存中读取一行。

它将结果存储在buffer中,一次最多包含chunk_size行,之后将结果保存到文件并清理buffer。这样一直持续到文件末尾。在读取循环结束时,如果缓冲区包含行,则会将其写入磁盘。

通过这种方式,除了检查内存中的行数之外,还可以检查磁盘写入数。每次读一行时都写文件可能不是一个好主意,并且chunk_size太大了。找到适合您问题的chunk_size值由您决定。

注意:您可以使用open() 缓冲参数来获得相同的结果。在documentation中查找所有内容。但是逻辑非常相似。

答案 1 :(得分:1)

尝试逐行读取文件,而不是一个大块。即

with open(writefilepath, "w", errors='ignore') as filew:
    with open(readfilepath, "r", errors='ignore') as filer:
       for line in filer:
           print("Line {}: {}".format(cnt, line.strip()))
           line = line.replace('| |', '|')
           filew.write(line)