Ce tutoriel explique en détail l'utilisation de la méthode tell() pour connaître la position courante dans un fichier, essentielle pour la manipulation précise des données.
1. Introduction à la méthode tell() des fichiers Python
La méthode tell() renvoie la position actuelle du pointeur de fichier (en octets) par rapport au début du fichier. Elle est indispensable lorsqu'on travaille avec seek() pour naviguer dans un fichier.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
# Syntaxe de base position = fichier.tell() # Exemple simple with open('exemple.txt', 'w') as f: f.write("Hello World!") with open('exemple.txt', 'r') as f: print(f"Position initiale : {f.tell()}") # 0 contenu = f.read(5) print(f"Après lecture de 5 caractères : {f.tell()}") # 5 contenu = f.read() print(f"Après lecture totale : {f.tell()}") # 12 |
2. La méthode tell() avec différents modes d'ouverture
Le comportement de tell() varie légèrement selon le mode d'ouverture du fichier (texte ou binaire).
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
# Mode texte vs mode binaire with open('test.txt', 'w', encoding='utf-8') as f: f.write("é") # Caractère accentué (2 octets en UTF-8) # Mode texte with open('test.txt', 'r', encoding='utf-8') as f: f.read(1) # Lit le caractère 'é' print(f"Position en mode texte : {f.tell()}") # 1 (compte en caractères) # Mode binaire with open('test.txt', 'rb') as f: f.read(1) # Lit le premier octet du caractère print(f"Position en mode binaire : {f.tell()}") # 1 (compte en octets) f.read(1) # Lit le deuxième octet print(f"Position après 2 octets : {f.tell()}") # 2 |
3. Combinaison des méthodes tell() et seek()
tell() et seek() sont souvent utilisées ensemble pour sauvegarder et restaurer des positions.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
# Sauvegarde et restauration de position with open('data.txt', 'w') as f: f.write("Ligne 1\nLigne 2\nLigne 3\n") with open('data.txt', 'r') as f: # Lire la première ligne premiere_ligne = f.readline() print(f"Première ligne : {première_ligne.strip()}") # Sauvegarder la position actuelle position_sauvegardee = f.tell() print(f"Position sauvegardée : {position_sauvegardee}") # Lire le reste du fichier reste = f.read() print(f"Reste du fichier : {reste}") # Revenir à la position sauvegardée f.seek(position_sauvegardee) print(f"Position après seek : {f.tell()}") # Relire depuis cette position ligne = f.readline() print(f"Relu depuis position sauvegardée : {ligne.strip()}") |
4. Cas pratiques d'utilisation de la méthode tell()
Exemples concrets où tell() est essentiel.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
# Cas 1 : Mesurer la taille d'un fichier def taille_fichier(nom_fichier): with open(nom_fichier, 'rb') as f: f.seek(0, 2) # Aller à la fin taille = f.tell() return taille # Création d'un fichier test with open('mesure.txt', 'w') as f: f.write("X" * 1000) print(f"Taille du fichier : {taille_fichier('mesure.txt')} octets") # Cas 2 : Traitement par blocs avec vérification def traiter_par_blocs(nom_fichier, taille_bloc=1024): with open(nom_fichier, 'rb') as f: while True: position_debut = f.tell() bloc = f.read(taille_bloc) if not bloc: break print(f"Bloc lu de {position_debut} à {f.tell()}") # Traitement du bloc ici... # Cas 3 : Détection de la position lors de l'écriture with open('journal.txt', 'a') as f: print(f"Position avant écriture : {f.tell()}") f.write("Nouvelle entrée\n") print(f"Position après écriture : {f.tell()}") f.write("Autre entrée\n") print(f"Position finale : {f.tell()}") |
5. Pièges courants et bonnes pratiques
Les erreurs fréquentes et comment les éviter.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
# Piège 1 : tell() en mode ajout ('a') with open('append.txt', 'a') as f: print(f"Position en mode 'a' : {f.tell()}") # Toujours à la fin f.write("test") print(f"Position après écriture : {f.tell()}") # Toujours à la fin # Piège 2 : Encodages multi-octets en mode texte with open('multi.txt', 'w', encoding='utf-8') as f: f.write("🎉") # Emoji (4 octets) with open('multi.txt', 'r', encoding='utf-8') as f: f.read(1) # Lit l'emoji complet print(f"Position pour 1 caractère emoji : {f.tell()}") # 1 (pas 4!) # Bonne pratique : Utiliser tell() pour déboguer def debug_position(fichier, operation): avant = fichier.tell() resultat = operation() apres = fichier.tell() print(f"{operation.__name__}: {avant} → {apres} (décalage: {apres - avant})") return resultat with open('debug.txt', 'w+') as f: f.write("Debug test") f.seek(0) # Utilisation du debug def lire_5_caracteres(): return f.read(5) debug_position(f, lire_5_caracteres) |
6. Exercice : Création d'un index de positions
Créer un index des positions de début de chaque ligne dans un fichier.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
def creer_index_lignes(nom_fichier): """Crée un index des positions de début de chaque ligne.""" index = [] with open(nom_fichier, 'r', encoding='utf-8') as f: while True: position = f.tell() ligne = f.readline() if not ligne: break index.append(position) return index def lire_ligne_par_index(nom_fichier, index, numero_ligne): """Lit une ligne spécifique en utilisant l'index.""" if numero_ligne >= len(index): return None with open(nom_fichier, 'r', encoding='utf-8') as f: f.seek(index[numero_ligne]) return f.readline().strip() # Test with open('livre.txt', 'w') as f: f.write("Chapitre 1\n") f.write("Il était une fois...\n") f.write("Fin du chapitre.\n") # Création de l'index index = creer_index_lignes('livre.txt') print(f"Index des positions : {index}") # Lecture via l'index for i in range(len(index)): ligne = lire_ligne_par_index('livre.txt', index, i) print(f"Ligne {i}: {ligne}") # Accès direct à une ligne spécifique print(f"\nLigne 1 directement : {lire_ligne_par_index('livre.txt', index, 1)}") |



