提问人:Alcott 提问时间:4/13/2012 更新时间:1/11/2022 访问量:512356
如何确定文件是否处于“eof”状态?
How to find out whether a file is at its `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 位于 eof。fp.tell()
read
此外,我认为您的示例代码实际上不起作用。据我所知,该方法永远不会返回,但它确实在 eof 上返回一个空字符串。read
None
评论
fp.tell()
OSError: telling position disabled by next() call
我认为从文件中读取是确定它是否包含更多数据的最可靠方法。它可能是一个管道,或者另一个进程可能正在将数据追加到文件中等。
如果您知道这不是问题,则可以使用类似以下内容:
f.tell() == os.fstat(f.fileno()).st_size
评论
''
fh.seek(0, 2); file_size = fh.tell(); fh.seek(0)
fh.tell() == file_size
os.fstat
f.tell()
os.fstat(f.fileno()).st_size
如果 Python 读取函数达到 EOF,它们将返回一个空字符串
fp.read()
读取到文件末尾,因此在成功完成后,您知道文件位于 EOF;无需检查。如果它无法到达 EOF,它将引发异常。
当以块而不是 的形式读取文件时,当返回的字节数小于请求的字节数时,您就知道您已经命中了 EOF。在这种情况下,以下调用将返回空字符串 (not )。以下循环以块形式读取文件;它最多会调用一次太多。read()
read
read
None
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)
评论
eof
fp.read(n)
n
for line in file: ...
if chunk == '':
if chunk == b'':
遇到 EOF 时,read 返回一个空字符串。文档在这里。
如果文件在非块模式下打开,返回的字节数少于预期并不意味着它处于 eof,我会说 @NPE 的答案是最可靠的方法:
f.tell() == os.fstat(f.fileno()).st_size
“for-else”设计经常被忽视。参见:Python 文档“控制循环中的流程”:
例
with open('foobar.file', 'rb') as f:
for line in f:
foo()
else:
# No more lines to be read from file
bar()
评论
else:
bar()
else
break
执行二进制 I/O 时,以下方法很有用:
while f.read(1):
f.seek(-1,1)
# whatever
优点是有时您正在处理二进制流,并且事先不知道需要读取多少内容。
评论
f.read(1)
f.read(1)
EOF
f.seek(-1,1)
bool('\0')
您可以使用以下代码片段逐行阅读,直到文件末尾:
line = obj.readline()
while(line != ''):
# Do Something
line = obj.readline()
f=open(file_name)
for line in f:
print line
评论
f = open(...)
with open(...) as f
f.close()
虽然我个人会使用语句来处理打开和关闭文件,但如果您必须从 stdin 读取并需要跟踪 EOF 异常,请执行如下操作:with
使用 try-catch 作为例外:EOFError
try:
input_lines = ''
for line in sys.stdin.readlines():
input_lines += line
except EOFError as e:
print e
由于 python 在 EOF 上返回空字符串,而不是“EOF”本身,因此您可以检查此处编写的代码
f1 = open("sample.txt")
while True:
line = f1.readline()
print line
if ("" == line):
print "file finished"
break;
评论
readline
"\n"
if not line: break
\n
readline()
\n
f.readline(
) 从文件中读取一行; 换行符 (\n
) 保留在字符串的末尾,如果文件不以换行符结尾,则仅在文件的最后一行省略。这使得返回值明确无误;如果 f.readline()
返回一个空字符串,则表示已到达文件末尾,而空行由“\n”
表示,该字符串仅包含一个换行符。
我使用这个功能:
# Returns True if End-Of-File is reached
def EOF(f):
current_pos = f.tell()
file_size = os.fstat(f.fileno()).st_size
return current_pos >= file_size
评论
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() 来确定文件末尾的位置。找到位置后,返回文件开头
评论
你可以通过调用方法到达后使用方法,如下所示:tell()
EOF
readlines()
fp=open('file_name','r')
lines=fp.readlines()
eof=fp.tell() # here we store the pointer
# indicating the end of the file in eof
fp.seek(0) # we bring the cursor at the begining of the file
if eof != fp.tell(): # we check if the cursor
do_something() # reaches the end of the file
评论
我真的不明白为什么python仍然没有这样的功能。我也不同意使用以下内容
f.tell() == os.fstat(f.fileno()).st_size
主要原因是在某些特殊条件下不太可能起作用。f.tell()
对我有用的方法如下。如果您有一些类似以下的伪代码
while not EOF(f):
line = f.readline()
" do something with line"
您可以将其替换为:
lines = iter(f.readlines())
while True:
try:
line = next(lines)
" do something with line"
except StopIteration:
break
此方法很简单,无需更改大部分代码。
分批读取文件(最后一批可以更短):BATCH_SIZE
BATCH_SIZE = 1000 # lines
with open('/path/to/a/file') as fin:
eof = False
while eof is False:
# We use an iterator to check later if it was fully realized. This
# is a way to know if we reached the EOF.
# NOTE: file.tell() can't be used with iterators.
batch_range = iter(range(BATCH_SIZE))
acc = [line for (_, line) in zip(batch_range, fin)]
# DO SOMETHING WITH "acc"
# If we still have something to iterate, we have read the whole
# file.
if any(batch_range):
eof = True
评论
获取文件的 EOF 位置:
def get_eof_position(file_handle):
original_position = file_handle.tell()
eof_position = file_handle.seek(0, 2)
file_handle.seek(original_position)
return eof_position
并将其与当前位置进行比较:。get_eof_position == file_handle.tell()
Python 没有内置的 eof 检测功能,但该功能可以通过两种方式获得:如果没有更多字节要读取,将返回。这适用于文本和二进制文件。第二种方法是用来查看当前寻道位置是否在末尾。如果您希望 EOF 测试不更改当前文件位置,那么您需要一些额外的代码。f.read(1)
b''
f.tell()
下面是这两种实现。
使用 tell() 方法
import os
def is_eof(f):
cur = f.tell() # save current position
f.seek(0, os.SEEK_END)
end = f.tell() # find the size of file
f.seek(cur, os.SEEK_SET)
return cur == end
使用 read() 方法
def is_eof(f):
s = f.read(1)
if s != b'': # restore position
f.seek(-1, os.SEEK_CUR)
return s == b''
如何使用它
while not is_eof(my_file):
val = my_file.read(10)
评论
if s: f.seek( ... )
# restore position
这是使用 Walrus Operator 执行此操作的方法(Python 3.8 中的新功能)
f = open("a.txt", "r")
while (c := f.read(n)):
process(c)
f.close()
有用的 Python 文档 (3.8):
海象操作员:https://docs.python.org/3/whatsnew/3.8.html#assignment-expressions
文件对象的方法:https://docs.python.org/3/tutorial/inputoutput.html#methods-of-file-objects
此代码适用于 python 3 及更高版本
file=open("filename.txt")
f=file.readlines() #reads all lines from the file
EOF=-1 #represents end of file
temp=0
for k in range(len(f)-1,-1,-1):
if temp==0:
if f[k]=="\n":
EOF=k
else:
temp+=1
print("Given file has",EOF,"lines")
file.close()
您可以尝试以下代码:
import sys
sys.stdin = open('input.txt', 'r') # set std input to 'input.txt'
count_lines = 0
while True:
try:
v = input() # if EOF, it will raise an error
count_lines += 1
except EOFError:
print('EOF', count_lines) # print numbers of lines in file
break
评论
with
语句 - 它可以很好地为您处理关闭和异常,并且阅读良好。