Python: отменить операцию чтения файла (), чтобы указатель файла вернулся в исходное состояние
Я просматриваю указатель на файл Python для текстового файла в режиме только для чтения с помощью file.readline() в поисках специальной строки. Как только я нахожу эту строку, я хочу передать указатель файла методу, который ожидает, что указатель файла будет в START этой строки чтения (не сразу после нее).
Как мне по существу отменить одну операцию file.readline() для указателя файла?
5 ответов
Вы должны запомнить положение, позвонив file.tell()
до чтения строки, а затем вызов 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
петля. Существует, вероятно, гораздо более питонный способ сделать это.
Вы записываете начальную точку линии с 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
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