Python: Undo un'operazione di file readline () in modo del file-pointer è di nuovo in stato originale

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

Domanda

Sono la navigazione attraverso un puntatore a file Python di un file di testo in modalità di sola lettura utilizzando file.readline () alla ricerca di una linea speciale. Una volta che trovo che la linea voglio passare il puntatore del file a un metodo che si aspetta il puntatore del file per essere al via di quella readline (non subito dopo.)

Come faccio essenzialmente ad annullare una file.readline () operazione su un puntatore a file?

È stato utile?

Soluzione

Si deve ricordare la posizione chiamando file.tell() prima della readline e quindi chiamando file.seek() per riavvolgere. Qualcosa di simile:

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

Non riesco a ricordare se è sicuro di chiamare file.seek() all'interno di un ciclo for line in file così io di solito solo scrivere il ciclo while. C'è probabilmente un modo molto più divinatorio di fare questo.

Altri suggerimenti

registrare il punto di partenza della linea con thefile.tell() prima di chiamare readline, e tornare a quel punto, se è necessario, con 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'
>>> 

, come si vede, il Seek / Tell "coppia" è "disfare", per così dire, il movimento del puntatore del file eseguito da readline. Naturalmente, questo può solo lavorare su un file effettivo posizionabili (cioè, disco), non (ad esempio) il file come oggetti costruiti w / il metodo makefile di prese, ecc ecc.

Se il metodo vuole semplicemente per scorrere il file, allora si potrebbe utilizzare itertools.chain per fare un iteratore appropriata:

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

Se non si conosce l'ultima riga perché non hai visita che si può leggere a ritroso fino a vedere un carattere nuova riga:

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
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top