Python: Annuler une opération readline () du fichier si le fichier pointeur est à nouveau en état d'origine

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

Question

Je navigation à travers un pointeur de fichier Python d'un fichier texte en mode lecture seule à l'aide file.readline () à la recherche d'une ligne spéciale. Une fois que je trouve cette ligne que je veux passer le pointeur de fichier à une méthode qui attend le pointeur de fichier pour être au début de ce readline (pas juste après.)

Comment annuler une opération essentiellement file.readline () sur un pointeur de fichier?

Était-ce utile?

La solution

Vous devez vous rappeler la position en appelant file.tell() avant la readline puis appeler file.seek() pour effectuer un retour. Quelque chose comme:

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

Je ne me souviens pas s'il est sûr d'appeler file.seek() à l'intérieur d'une boucle de for line in file donc généralement je viens d'écrire la boucle while. Il y a probablement une manière beaucoup plus pythonique de le faire.

Autres conseils

Vous enregistrez le point de départ de la ligne avec thefile.tell() avant d'appeler readline, et revenez à ce moment-là, si vous avez besoin, avec 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'
>>> 

comme vous le voyez, la recherche / tell « paire » est « Défaire », pour ainsi dire, le mouvement du pointeur de fichier effectué par readline. Bien sûr, cela ne peut fonctionner sur un fichier adressable réel (à savoir, disque), non (par exemple) sur fichiers comme des objets construits w / la méthode makefile de sockets, etc etc.

Si votre méthode veut simplement itérer dans le fichier, vous pouvez ensuite utiliser itertools.chain pour faire un itérateur approprié:

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

Si vous ne connaissez pas la dernière ligne parce que vous ne l'avez pas le visiter, vous pouvez lire en arrière jusqu'à ce que vous voyez un caractère de nouvelle ligne:

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
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top