如何找出文件是否在`eof`?

fp = open("a.txt") #do many things with fp c = fp.read() if c is None: print 'fp is at the eof' 

除了上面的方法,还有其他什么方法来查明是否fp已经在eof?

fp.read()读取到文件的末尾,所以在成功完成后,你知道文件在EOF; 没有必要检查 如果无法达到EOF,则会引发exception。

当以块读取文件而不是使用read() ,当read返回小于您请求的字节数时,您知道已经命中了EOF。 在这种情况下,下面的read调用将返回空string(不是None )。 以下循环以块forms读取文件; 最多一次会打电话多read一次。

 assert n > 0 while True: chunk = fp.read(n) if chunk == '': break process(chunk) 

或者,更短:

 for chunk in iter(lambda: fp.read(n), ''): process(chunk) 

“其他”devise往往被忽视。 请参阅: Python文档“循环中的控制stream” :

 with open('foobar.file', 'rb') as f: for line in f: foo() else: # No more lines to be read from file bar() 

我认为从文件中读取是确定是否包含更多数据的最可靠的方法。 它可能是一个pipe道,或另一个进程可能是附加数据的文件等

如果你知道这不是一个问题,你可以使用像这样的东西:

 f.tell() == os.fstat(f.fileno()).st_size 

在执行二进制I / O时,以下方法很有用:

 while f.read(1): f.seek(-1,1) # whatever 

好处是,有时候你正在处理一个二进制stream,而且事先不知道你需要阅读多less。

您可以在调用read方法之前和之后比较fp.tell()的返回值。 如果他们返回相同的值,那么fp就是eof。

此外,我不认为你的例子代码实际上工作。 据我所知, read方法永远不会返回None ,但它确实会在eof上返回一个空string。

当遇到EOF时,读取返回一个空string。 文档在这里 。

 f=open(file_name) for line in f: print line 

Python读取函数将返回一个空string,如果他们到达EOF

如果文件以非阻塞模式打开,返回比预期更less的字节并不意味着它在eof,我会说@ NPE的答案是最可靠的方法:

f.tell()== os.fstat(f.fileno())。st_size

由于Python在EOF上返回空string,而不是“EOF”本身,所以只需检查它的代码,写在这里

 f1 = open("sample.txt") while True : line = f1.readline() print line if ("" == line): print "file finished" break; 

尽pipe我会亲自使用with语句来处理打开和closures文件,但是在必须从stdin读取并需要跟踪EOFexception的情况下,请执行以下操作:

使用EOFError的try-catch作为例外:

 try: input_lines = '' for line in sys.stdin.readlines(): input_lines += line except EOFError as e: print e 
 f = open(filename,'r') f.seek(-1,2) # go to the file end. eof = f.tell() # get the end of file location f.seek(0,0) # go back to file beginning while(f.tell() != eof): <body> 

您可以使用文件方法 seek()tell()来确定文件结尾的位置。 一旦find位置,请回到文件的开头

我使用这个function:

 def EOF(f): current_pos = f.tell() file_size = os.fstat(f.fileno()).st_size return current_pos < file_size 

你可以使用下面的代码片段逐行阅读,直到文件结尾:

 line = obj.readline() while(line != ''): # Do Something line = obj.readline()