Je suis en train de parcourir un pointeur de fichier Python d'un fichier texte en mode lecture seule, en utilisant file.readline () à la recherche d'une ligne spéciale. Une fois que je trouve cette ligne, je veux passer le pointeur de fichier à une méthode qui attend du pointeur de fichier au début de cette ligne de lecture (pas juste après).
Comment puis-je essentiellement annuler une opération file.readline () sur un pointeur de fichier?
Vous devez vous rappeler la position en appelant file.tell()
avant la ligne de lecture, puis en appelant file.seek()
pour revenir en arrière. 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 plus s'il est sûr d'appeler file.seek()
à l'intérieur d'une boucle for line in file
, aussi j'écris généralement la boucle while
. Il y a probablement une manière beaucoup plus pythonique de le faire.
Vous enregistrez le point de départ de la ligne avec thefile.tell()
avant d'appeler readline
et vous revenez à ce point, si nécessaire, 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, le "couple" cherche/dit est "défait", pour ainsi dire, le mouvement du pointeur de fichier effectué par readline
. Bien sûr, cela ne peut fonctionner que sur un fichier réel à rechercher (disque), pas (par exemple) sur des objets de type fichier construits avec la méthode makefile de sockets, etc.
Si votre méthode veut simplement parcourir le fichier, vous pouvez utiliser itertools.chain
pour créer 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 visitée, vous pouvez lire à l'envers jusqu'à ce que vous voyiez 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