web-dev-qa-db-ja.com

ファイルが「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にあるかどうかを確認する他の方法はありますか?

51
Alcott

fp.read()はファイルの最後まで読み取るため、正常に終了すると、ファイルがEOFにあることがわかります。確認する必要はありません。 EOFに到達できない場合、例外が発生します。

read()ではなくチャンク単位でファイルを読み取る場合、readが要求したバイト数より少ない値を返したときにEOFにヒットしたことがわかります。その場合、次のread呼び出しは空の文字列を返します(Noneではありません)。次のループは、ファイルをチャンクで読み取ります。 readを1回しか呼び出しません。

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

または、短い:

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

「その他」の設計は見過ごされがちです。参照: Pythonドキュメント「ループ内の制御フロー」

with open('foobar.file', 'rb') as f:
    for line in f:
        foo()

    else:
        # No more lines to be read from file
        bar()
47
Blake Atkinson

ファイルからの読み取りが、より多くのデータが含まれているかどうかを確認する最も信頼できる方法であると主張します。パイプの場合もあれば、別のプロセスがファイルなどにデータを追加している場合もあります。

knowそれが問題ではない場合、次のようなものを使用できます。

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

バイナリI/Oを実行する場合、次の方法が役立ちます。

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

利点は、バイナリストリームを処理しているときに、どれだけ読む必要があるかが事前にわからないことです。

10
user545424

readメソッドを呼び出す前後で、fp.tell()の戻り値を比較できます。それらが同じ値を返す場合、fpはeofにあります。

さらに、サンプルコードが実際に機能するとは思わない。私の知る限り、readメソッドはNoneを決して返しませんが、eofで空の文字列を返します。

8

pythonは、EOF自体ではなくEOFで空の文字列を返すため、ここに記述されたコードを確認するだけです。

f1 = open("sample.txt")

while True:
    line = f1.readline()
    print line
    if ("" == line):
        print "file finished"
        break;
8
tingtong

EOFが検出されると、readは空の文字列を返します。ドキュメントは here です。

7
01100110
f=open(file_name)
for line in f:
   print line
6
samba

ファイルが非ブロックモードで開かれている場合、返されるバイト数が予想より少ないということは、eofであるという意味ではありません。@ NPEの答えが最も信頼できる方法だと思います。

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

4
ymattw

なぜ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

この方法は簡単で、ほとんどのコードを変更する必要はありません。

4
Han Luo

Python読み取り関数は、EOFに達すると空の文字列を返します

2
mensi
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()ファイルの終わりの位置を決定します。位置が見つかったら、ファイルの先頭からシークします

1
Newstein

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
1
wamba

ファイルの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()

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
0
boechat107

Pythonにはeof検出関数が組み込まれていませんが、その機能は2つの方法で利用できます。f.read(1)は、読み取るバイトがなくなるとb''を返します。これは、テキストファイルとバイナリファイルの両方で機能します。 2番目の方法は、f.tell()を使用して、現在のシーク位置が最後にあるかどうかを確認することです。 EOFテストで現在のファイルの位置を変更しないようにするには、少し余分なコードが必要です。

以下は両方の実装です。

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)

このコードで再生

0
Shital Shah

個人的にwithステートメントを使用してファイルの開閉を処理しますが、stdinから読み取る必要があり、EOF例外を追跡する必要がある場合は、次のようにします。

例外としてEOFErrorを使用してtry-catchを使用します。

try:
    input_lines = ''
    for line in sys.stdin.readlines():
        input_lines += line             
except EOFError as e:
    print e
0
Blairg23