Python: Undo eine Datei Readline- () -Operation so Datei-Pointer ist wieder im ursprünglichen Zustand

StackOverflow https://stackoverflow.com/questions/3505479

Frage

Ich bin gerade durch einen Python-Datei Zeiger einer Textdatei im Nur-Lese-Modus file.readline () auf der Suche nach einer speziellen Linie. Sobald ich diese Zeile finden möchte ich die Datei Zeiger auf eine Methode zu übergeben, die den Dateizeiger erwarten am Anfang dieser Readline- zu sein (nicht direkt nach dem Spiel.)

Wie im wesentlichen ich rückgängig macht einen file.readline () Operation auf einem Dateizeiger?

War es hilfreich?

Lösung

Sie haben die Position erinnern file.tell() vor dem Readline- aufrufen und dann file.seek() zurückzuspulen aufrufen. So etwas wie:

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()

Ich kann mich nicht erinnern, ob es sicher ist file.seek() innerhalb eines for line in file Schleife zu nennen, damit ich in der Regel nur die while Schleife auszuschreiben. Es ist wahrscheinlich eine viel pythonic Art und Weise, dies zu tun.

Andere Tipps

Sie den Startpunkt der Linie mit thefile.tell() aufzuzeichnen, bevor Sie readline rufen, und zu diesem Punkt zurück, wenn es nötig ist, mit 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'
>>> 

Wie Sie sehen, die Seek / tell „Paar“ wird „rückgängig gemacht“, so zu sprechen, führte die Dateizeigerbewegung durch readline. Natürlich kann dies nur die Arbeit an einer tatsächlichen seekable (das heißt, Disk-Datei), nicht (z) auf dateiähnliche Objekten w / Makefile-Methode von Steckdosen eingebaut, etc etc.

Wenn Ihre Methode einfach zu wiederholen durch die Datei will, dann könnte man itertools.chain verwenden, um eine geeignete Iterator zu machen:

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

Wenn Sie nicht die letzte Zeile wissen, weil Sie es nicht besuchen Sie können rückwärts gelesen, bis ein Newline-Zeichen zu sehen:

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
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top