2010-10-11 47 views
56

对于我正在做的练习,我试图用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()两次?我必须重置文件句柄吗?或者关闭/重新打开文件,以此来做到这一点?

+2

你从哪里得到读取不会改变文件状态的想法?您使用的是什么参考或教程? – 2010-10-11 12:29:31

+0

我相信关闭和重新打开该文件应该基于下面的anwers工作。 – Anthony 2010-10-11 12:29:59

+0

@Shynthriir:关闭并重新打开文件并不总是一个好主意,因为它可能在系统中有其他影响(临时文件,incron等)。 – 2010-10-11 12:32:22

回答

88

调用read()会读取整个文件,并将读取光标保留在文件的末尾(没有其他可读的内容)。如果您想要一次读取一定数量的行,则可以使用readline()readlines()或通过与for line in handle:重复行。

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

Ps。不要忘了在完成之后关闭文件;)

+3

+1,是的,请阅读临时变量避免不必要的文件I/O。这是一个虚假的经济,因为你有更少的(显式)变量,所以你正在保存任何内存。 – 2010-10-11 13:45:03

+2

@NickT:我期望一个被多次读取的小文件被操作系统缓存(至少在Linux/OSX上),所以没有额外的文件I/O来读取两次。不适合内存的大文件不会被缓存,但您不想将它们读入变量,因为您将开始交换。所以如有疑问,请多阅读一次。如果你确定文件很小,那么请做出最好的程序。 – Claude 2014-06-04 13:41:04

+0

使用['with'](http://effbot.org/zone/python-with-statement.htm)可以实现自动拆除。 – 2016-01-19 16:47:56

13

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

2

每个打开的文件都有一个关联的位置。
当你阅读()你从那个位置读取。 例如read(10)从新打开的文件中读取前10个字节,然后另一个read(10)读取下10个字节。 read()无参数读取文件的所有内容,并将文件位置保留在文件末尾。您下次拨打read()时,没有什么可读的。

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

13

到目前为止回答这个问题的人都是绝对正确的 - 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 
+1

+1其实这是本练习的建议解决方案(http://code.google.com/intl/de-DE/edu/languages/google-python-class/exercises/baby-names.html)。但不知何故,我没有想到将字符串存储在变量中。 D'哦! – helpermethod 2010-10-11 17:33:23

+1

在Python3中,使用pathlib。 '从pathlib导入路径; text =路径(文件名).read_text()'照顾打开,关闭等。 – PaulMcG 2017-06-19 12:06:20

1

read()消耗。所以,你可以重置这个文件,或者重新开始阅读之前。或者,如果它适合您的任务,则可以使用read(n)仅消耗n字节。

12

是的,如上...

我会写只是一个例子:

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

我总是觉得散步的读法的东西下来一个黑暗的胡同。你稍微停下来,但如果你不计算你的步数,你不知道你有多远。 Seek通过重新定位给出解决方案,另一个选项是Tell,它返回文件的位置。可能是Python文件API可以将读取和查找结合到一个read_from(位置,字节)以使其更简单 - 直到发生这种情况,您应该阅读this page

相关问题