IT-Swarm.Net

为什么我不能在打开的文件上调用read()两次?

对于我正在进行的练习,我试图使用read()方法两次读取给定文件的内容。奇怪的是,当我第二次调用它时,它似乎没有将文件内容作为字符串返回?

这是代码

f = f.open()

# get the year
match = re.search(r'Popularity in (\d+)', f.read())

if match:
  print match.group(1)

# get all the names
matches = re.findall(r'<td>(\d+)</td><td>(\w+)</td><td>(\w+)</td>', f.read())

if matches:
  # matches is always None

当然我知道这不是最有效或最好的方式,这不是重点。关键是,为什么我不能两次调用read()?我是否必须重置文件句柄?或者关闭/重新打开文件以执行此操作?

80
helpermethod

调用read()会读取整个文件,并将读取光标留在文件末尾(无需读取任何内容)。如果您希望一次读取一定数量的行,可以使用readline()readlines()或使用for line in handle:遍历行。.

要直接回答您的问题,一旦读取了文件,使用read()就可以使用seek(0)将读取光标返回到文件的开头(文档是 here )。如果您知道文件不会太大,您还可以将read()输出保存到变量中,并在findall表达式中使用它。.

PS。完成之后别忘了关闭文件;)

130
Tim

快速,可靠且价格合理的云托管

注册并在30天内获得$50奖金!

是的,如上所述......

我只写一个例子:

>>> a = open('file.txt')
>>> a.read()
#output
>>> a.seek(0)
>>> a.read()
#same output
21
Ant

到目前为止回答这个问题的每个人都是绝对正确的 - read()在文件中移动,所以在你调用它之后,你不能再次调用它。.

我要补充的是,在您的特定情况下,您不需要寻找开头或重新打开文件,您只需将您在本地变量中读取的文本存储起来,并使用它两次,或者在您的计划中,您可以多次使用:

f = f.open()
text = f.read() # read the file into a local variable
# get the year
match = re.search(r'Popularity in (\d+)', text)
if match:
  print match.group(1)
# get all the names
matches = re.findall(r'<td>(\d+)</td><td>(\w+)</td><td>(\w+)</td>', text)
if matches:
  # matches will now not always be None
16
Tom Anderson

读指针移动到最后读取的字节/字符之后。使用seek()方法将读指针倒回到开头。.

13
Ignacio Vazquez-Abrams

每个打开的文件都有相关的位置。.
当你读()时,你从那个位置读。例如read(10)从新打开的文件中读取前10个字节,然后另一个read(10)读取接下来的10个字节。没有参数的read()读取文件的所有内容,将文件位置保留在文件的末尾。下次调用read()时,无需阅读。.

您可以使用seek来移动文件位置。或者在你的情况下可能更好的做一个read()并保留两个搜索的结果。.

2
Douglas Leeder

我总是觉得读取方法有点走在黑暗的小巷里。你走了一段路然后停下来,但如果你不计算你的步数,你就不知道你走了多远。 Seek通过重新定位给出解决方案,另一个选项是Tell,它返回文件中的位置。可能是Python文件api可以将read和seek组合成read_from(位置,字节)以使其更简单 - 直到发生这种情况你应该阅读 这个页面 。.

1
whatnick

read() 消耗。因此,您可以在重新读取之前 重置 文件,或 搜索 到开头。或者,如果它适合您的任务,您可以使用read(n)仅使用n字节。.

1
towi