file.readline()を使用して、読み取り専用モードでテキストファイルのPythonファイルポインタを参照して、特別な行を探しています。その行を見つけたら、ファイルポインタがそのreadlineの先頭(直後ではない)にあることを期待しているメソッドにファイルポインタを渡します。
ファイルポインタに対する1つのfile.readline()操作を基本的に元に戻すにはどうすればよいですか?
file.tell()
readlineの前に呼び出してから、巻き戻しを呼び出すことによって、位置を覚えておく必要がありますfile.seek()
。何かのようなもの:
fp = open('myfile')
last_pos = fp.tell()
line = fp.readline()
while line != '':
if line == 'SPECIAL':
fp.seek(last_pos)
other_function(fp)
break
last_pos = fp.tell()
line = fp.readline()
file.seek()
ループ内で安全に呼び出すことができるかどうか思い出せないfor line in file
ので、通常はループを書き出すだけwhile
です。これを行うには、おそらくもっとPython的な方法があります。
thefile.tell()
を呼び出す前に、で行の始点を記録し、readline
必要に応じて、でその点に戻りますthefile.seek
。
>>> with open('bah.txt', 'w') as f:
... f.writelines('Hello %s\n' % i for i in range(5))
...
>>> with open('bah.txt') as f:
... f.readline()
... x = f.tell()
... f.readline()
... f.seek(x)
... f.readline()
...
'Hello 0\n'
'Hello 1\n'
'Hello 1\n'
>>>
ご覧のとおり、シーク/テルの「ペア」は「元に戻す」、いわば、によって実行されるファイルポインタの移動readline
です。もちろん、これは実際のシーク可能な(つまり、ディスク)ファイルでのみ機能し、(たとえば)ソケットなどのmakefileメソッドで構築されたファイルのようなオブジェクトでは機能しません。
メソッドが単にファイルを反復処理したい場合はitertools.chain
、適切な反復子を作成するために使用できます。
import itertools
# do something to the marker line and everything after
def process(it):
for line in it:
print line,
with open(filename,'r') as f:
for line in f:
if 'marker' in line:
it=itertools.chain((line,),f)
process(it)
break
fin = open('myfile')
for l in fin:
if l == 'myspecialline':
# Move the pointer back to the beginning of this line
fin.seek(fin.tell() - len(l))
break
# now fin points to the start of your special line
最後の行にアクセスしなかったために最後の行がわからない場合は、改行文字が表示されるまで逆方向に読むことができます。
with open(logfile, 'r') as f:
# go to EOF
f.seek(0, os.SEEK_END)
nlines = f.tell()
i=0
while True:
f.seek(nlines-i)
char = f.read(1)
if char=='\n':
break
i+=1