87 votes

Comment savoir si un fichier est à son `eof` ?

fp = open("a.txt")
#do many things with fp

c = fp.read()
if c is None:
    print 'fp is at the eof'

Outre la méthode ci-dessus, existe-t-il un autre moyen de savoir si fp est déjà à l'eof ?

6 votes

Cela vaut la peine de jeter un coup d'œil à la with déclaration pour l'ouverture des fichiers - il gère la fermeture et les exceptions pour vous de manière agréable, et se lit bien.

82voto

larsmans Points 167484

fp.read() lit jusqu'à la fin du fichier, donc après qu'il ait terminé avec succès, vous savez que le fichier est à EOF ; il n'y a pas besoin de vérifier. S'il ne peut pas atteindre EOF, il lèvera une exception.

Lors de la lecture d'un fichier par morceaux plutôt qu'avec read() vous savez que vous avez atteint EOF lorsque read renvoie un nombre d'octets inférieur à celui que vous avez demandé. Dans ce cas, la commande suivante read retournera la chaîne vide (pas None ). La boucle suivante lit un fichier par morceaux ; elle appelle read au maximum une fois de trop.

assert n > 0
while True:
    chunk = fp.read(n)
    if chunk == '':
        break
    process(chunk)

Ou, plus court :

for chunk in iter(lambda: fp.read(n), ''):
    process(chunk)

55voto

Blake Atkinson Points 1001

La conception "for-else" est souvent négligée. Voir : Docs Python "Control Flow in Loop" (flux de contrôle en boucle) :

Exemple

with open('foobar.file', 'rb') as f:
    for line in f:
        foo()

    else:
        # No more lines to be read from file
        bar()

45 votes

Il n'y a littéralement aucun intérêt à cela. else: . Ne pas l'écrire et juste avoir bar() fonctionne de la même manière. else ne fait de différence que si vous utilisez break .

2 votes

Quelqu'un pourrait lire ceci et s'en soucier :) Je ne savais pas qu'on pouvait itérer sur f ligne par ligne (même en mode binaire !). Je ne suis pas fan d'autre chose : ça ne sert à rien, ça ne fait qu'ajouter une ligne et plus de code indenté. Son but et son comportement sont confus tout comme finally dans try/except.

35voto

NPE Points 169956

Je dirais que la lecture du fichier est le moyen le plus fiable d'établir s'il contient plus de données. Il peut s'agir d'un tuyau, ou un autre processus peut ajouter des données au fichier, etc.

Si vous connaître ce n'est pas un problème, vous pourriez utiliser quelque chose comme :

f.tell() == os.fstat(f.fileno()).st_size

0 votes

Il est convenu que si vous appelez read() et que vous êtes à EOF il va retourner ''

7 votes

Je préfère fh.seek(0, 2); file_size = fh.tell(); fh.seek(0) à l'avance et ensuite fh.tell() == file_size plus tard. Y a-t-il un avantage à procéder de cette façon ? REMARQUE : je vous suggère de mettre en cache la taille dans une variable et de ne pas appeler os.fstat sur chaque boucle.

3 votes

Notez que cela ne fonctionnera pas si le fichier est ouvert en mode texte : f.tell() vous donne la position du fichier en caractères et os.fstat(f.fileno()).st_size vous donne la longueur du fichier en octets. La méthode de @BrunoBronosky fonctionnera cependant.

23voto

tingtong Points 215

Comme python renvoie une chaîne vide sur EOF, et non "EOF" lui-même, vous pouvez simplement vérifier le code pour cela, écrit ici

f1 = open("sample.txt")

while True:
    line = f1.readline()
    print line
    if ("" == line):
        print "file finished"
        break;

10 votes

Une ligne vide dans le fichier casse cet algorithme.

16 votes

@LeonardoRaele : une ligne vide causerait readline pour revenir "\n" . Il ne renvoie une chaîne vide que si le fichier est effectivement à EOF.

2 votes

Pourquoi pas ? if not line: break ?

15voto

user545424 Points 3707

Lorsque vous effectuez des E/S binaires, la méthode suivante est utile :

while f.read(1):
    f.seek(-1,1)
    # whatever

L'avantage est que parfois vous traitez un flux binaire et ne savez pas à l'avance combien vous devrez lire.

0 votes

Comment cela vous indique-t-il si vous êtes à l'EOF ?

0 votes

@GreenAsJade, f.read(1) retournera la chaîne vide à EOF.

0 votes

Huh ! Et... la recherche est-elle essentielle, et ne fait-elle pas simplement partie d'un quelconque élément ? Quel est son rôle ?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X