循环读取大文件

Reading large files in a loop

当我想读取它们并在 while 循环中使用它们时,我在处理大型文本文件(大约 1GB)时遇到了一些麻烦。

更具体地说:首先,我首先对文件的行进行一些解析,以便找到例如所有以 "x" 开头的行。为此,我将找到的行的索引添加到列表中(比如 l)。这是预处理部分。

现在在 while 循环中,我从 l 中选择随机索引,并希望读取其对应的行(或者说它周围的 5 行)。因此,我需要在整个 while 循环中一劳永逸地将文件保存在内存中,作为先验,我不知道我最终读取了哪些行(该行是从 l 中随机挑选的)。

问题是,当我在主循环之前调用文件时,在循环的第一个 运行 期间,读取成功完成,但已经从第二个 运行 开始,文件已经从记忆中消失了。我尝试过的:

预处理部分:

for i, line in enumerate(filename):
    prep = ''.join(c for c in line if c.isalnum() or c.isspace())
    if 'x' in prep: l.append(i)

现在我有了我的 l 列表。在主循环之前将文件加载到内存中:

with open(filename,'r') as f:
    while (some condition):
        random_index = random.sample(range(0,len(l)),1)
        output_file = open("out","w") #I will write here the read line(s)
        for i, line in enumerate(f):
            #(the lines to be read, starting from the given random index)
            if (i >= l[random_index]) and (i < l[random_index+1]): 
                out.write(line)
        out.close()

仅在循环的第一个 运行 期间,一切正常。 或者我也试过:

f = open(filename)
while (some condition):
    random_index = ... #rest is same as above.

同样的问题,只有第一个 运行 有效。一件可行的事情是将 f=open(filename) 放入循环中,因此每个 运行 文件都会被调用。但是因为它很大,所以这真的不是一个实用的解决方案。

What am I doing wrong here?

This answer 解决了同样的问题:你不能读取文件两次。

您在 while 循环之外打开文件 f,并在 while 循环的第一次迭代期间通过调用 for i, line in enumerate(f): 完整读取它。在第二次迭代期间,您无法再次阅读它,因为它已经被阅读过了。

How should such readings be done properly?

如链接答案中所述:

To answer your question directly, once a file has been read, with read() you can use seek(0) to return the read cursor to the start of the file (docs are here).

这意味着,要解决您的问题,您可以在 while 循环的末尾添加 f.seek(0) 以在每次迭代后将指针移动到文件的开头。这样做你可以重新从头开始读取文件。