循环读取大文件
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)
以在每次迭代后将指针移动到文件的开头。这样做你可以重新从头开始读取文件。
当我想读取它们并在 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 useseek(0)
to return the read cursor to the start of the file (docs are here).
这意味着,要解决您的问题,您可以在 while
循环的末尾添加 f.seek(0)
以在每次迭代后将指针移动到文件的开头。这样做你可以重新从头开始读取文件。