Bonjour,
Y a t'il un moyen de lire le dernier record d'un fichier sans lire tout le fichier ?
Merci
Bonjour,
Y a t'il un moyen de lire le dernier record d'un fichier sans lire tout le fichier ?
Merci
Salut,
Les fichiers sont gérés par l'OS et Python ne fait que s'interfacer avec les primitives correspondantes.
La fonction seek permet de positionner l'endroit qui affectera la prochaine opération sur le fichier (qu'on peut considérer comme un tableau de bytes).
Si les "records" sont de taille fixe, le début du record N sera simple à calculer.
S'ils sont de longueur variable, il faudra rechercher le délimiteur qui matérialise le début du dernier record => lire les blocks de fin et y rechercher le dernier record.
- W
Bonjour,
Oui, c'est possible en utilisant la méthode évoquée par wiztricks: lire le fichier sous forme binaire (blocs d'octets), chercher les fins de lignes ('\n' suffit pour Windows et Linux) et s'arrêter à la dernière ou à l'avant dernière, lire l'adresse (tell) et charger la ligne (seek). Attention au piège: quelquefois la dernière ligne est vide et c'est l'avant dernière qu'il faut garder. Autre piège: si l'encodage permet à certains caractères composites d'avoir un octet identique à la fin de ligne: ça ne marche plus (je n'ai pas vérifié que c'est possible avec l'unicode, mais il n'y a pas de problème avec les encodages courants).
Il y a quelques temps, je m'étais amusé à compter le nombre de lignes d'un fichier texte sans lire les lignes: ça marche très bien, et c'est 10 fois plus rapide. Il doit y avoir des choses à récupérer pour ce problème. Mon tuto est ici: http://python.jpvweb.com/mesrecettes...lignes_fichier.
Un expert est une personne qui a fait toutes les erreurs qui peuvent être faites, dans un domaine étroit... (Niels Bohr)
Mes recettes python: http://www.jpvweb.com
Salut,
S'il est utile de montrer l'utilisation de .seek et de .tell pour lire les n dernières lignes d'un fichier texte, on peut le faire ainsi:
Nota le "record" est alors délimité par la fin de ligne, ce qui n'est pas forcément ce que cherche le PO.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 def tail(f, n): """Reads last n lines from f """ avg_length = 74 while 1: try: f.seek(-(avg_length * n), 2) except IOError: # assume file is not large enough f.seek(0) pos = f.tell() lines = f.read().splitlines() if len(lines) >= n or pos == 0: return lines[-n:] avg_length *= 1.3
Comme on se contente de lire la fin du fichier, pas la peine d'essayer d'optimiser la recherche des fin de lignes ('\n').
.splitlines fait cela très bien et çà simplifie pas mal les choses.
- W
Salut
Normalement le seek ne s'utilise qu'en binaire à cause des différences de fin de lignes dans les différents OS. Chez microsoft par exemple le fin de ligne fait 2 bytes de long, un sous linux/unix. Donc un fseek peut ne pas donner le même résultat d'une machine à une autre. Si tu utilises de l'utf-8, un caractère peut faire plusieurs octets. Donc, tu pourras certes te positionner x bytes avant la fin, mais pas x caractères avant la fin.
A+
Pfeuh
Pas besoin de connaitre le nombre de bytes du fichier (i.e. la fin), la méthode .seek prend un offset qui s'applique depuis le début, la position courante ou à partir de la fin.
Relisez l'exemple que j'ai posté
Tout est dans "f.seek(-(avg_length * n), 2):
- "2" indique "à partir de la fin"
- -(avg_length * n) est un offset négatif
On se positionne à (avg_length * n) avant la fin et le .read qui vient ensuite retourne ce qu'il trouve de cette position "jusqu'à la fin" du fichier.
Enfin .splitlines découpe ce qui a été récupéré en "lignes" au sens Python.
=> la dernière ligne sera comptée quelle se termine ou pas d'un '\n'
- W
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager