web-dev-qa-db-fra.com

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, n’importe quel autre moyen de savoir si fp est déjà au point

45
Alcott

fp.read() lit jusqu'à la fin du fichier. Ainsi, une fois l'opération terminée, vous savez que le fichier est à l'état EOF. il n'y a pas besoin de vérifier. S'il ne peut pas atteindre EOF, une exception sera levée.

Lorsque vous lisez un fichier par fragments plutôt que avec read(), vous savez que vous avez appuyé sur EOF lorsque read renvoie moins que le nombre d'octets que vous avez demandé. Dans ce cas, l'appel read suivant renverra la chaîne vide (pas None). La boucle suivante lit un fichier par morceaux; il appellera read au plus 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)
47
Fred Foo

La conception "pour-sinon" est souvent négligée. Voir: Python Docs "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()
41
Blake Atkinson

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

Si vous savez ce n'est pas un problème, vous pouvez utiliser quelque chose comme:

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

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 vous traitez parfois un flux binaire et que vous ne savez pas à l'avance combien de temps vous aurez besoin de lire.

10
user545424

Vous pouvez comparer la valeur renvoyée de fp.tell() avant et après l'appel de la méthode read. S'ils renvoient la même valeur, fp est à eof.

De plus, je ne pense pas que votre exemple de code fonctionne réellement. À ma connaissance, la méthode read ne renvoie jamais None, mais renvoie une chaîne vide sur eof.

8
Lauritz V. Thaulow

read renvoie une chaîne vide lorsque EOF est rencontré. Les docs sont ici .

7
01100110

Comme python retourne une chaîne vide sur EOF, et non "EOF", vous pouvez simplement vérifier le code, écrit ici

f1 = open("sample.txt")

while True:
    line = f1.readline()
    print line
    if ("" == line):
        print "file finished"
        break;
6
tingtong
f=open(file_name)
for line in f:
   print line
5
samba

Si le fichier est ouvert en mode sans blocage, si le nombre d'octets renvoyés est inférieur à la valeur attendue, la réponse de @ NPE est la méthode la plus fiable:

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

4
ymattw

Je ne comprends vraiment pas pourquoi python n'a toujours pas cette fonction. Je n'accepte pas non plus d'utiliser ce qui suit

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

La raison principale est que f.tell() ne fonctionne probablement pas pour certaines conditions spéciales.

La méthode fonctionne pour moi est comme suit. Si vous avez un pseudo-code comme celui-ci

while not EOF(f):
     line = f.readline()
     " do something with line"

Vous pouvez le remplacer par:

lines = iter(f.readlines())
while True:
     try:
        line = next(lines)
        " do something with line"
     except StopIteration:
        break

Cette méthode est simple et vous n'avez pas besoin de changer la plupart de votre code.

2
Han Luo

Les fonctions de lecture Python renverront une chaîne vide si elles atteignent EOF

2
mensi
f = open(filename,'r')
f.seek(-1,2)     # go to the file end.
eof = f.tell()   # get the end of file location
f.seek(0,0)      # go back to file beginning

while(f.tell() != eof):
    <body>

Vous pouvez utiliser les méthodes fileseek () et tell () pour déterminer la position de la fin du fichier. Une fois la position trouvée, retournez au début du fichier

1
Newstein

Vous pouvez utiliser la méthode tell() après avoir atteint EOF en appelant la méthode readlines().__, comme ceci:

fp=open('file_name','r')
lines=fp.readlines()
eof=fp.tell() # here we store the pointer
              # indicating the end of the file in eof
fp.seek(0) # we bring the cursor at the begining of the file
if eof != fp.tell(): # we check if the cursor
     do_something()  # reaches the end of the file
1
wamba

Obtenir la position EOF du fichier:

def get_eof_position(file_handle):
    original_position = file_handle.tell()
    eof_position = file_handle.seek(0, 2)
    file_handle.seek(original_position)
    return eof_position

et comparez-le avec la position actuelle: get_eof_position == file_handle.tell().

Lire un fichier par lots de BATCH_SIZE lignes (le dernier lot peut être plus court):

BATCH_SIZE = 1000  # lines

with open('/path/to/a/file') as fin:
    eof = False
    while eof is False:
        # We use an iterator to check later if it was fully realized. This
        # is a way to know if we reached the EOF.
        # NOTE: file.tell() can't be used with iterators.
        batch_range = iter(range(BATCH_SIZE))
        acc = [line for (_, line) in Zip(batch_range, fin)]

        # DO SOMETHING WITH "acc"

        # If we still have something to iterate, we have read the whole
        # file.
        if any(batch_range):
            eof = True
0
boechat107

Python ne possède pas de fonction de détection eof intégrée, mais cette fonctionnalité est disponible de deux manières: f.read(1) renverra b'' s'il n'y a plus d'octets à lire. Cela fonctionne aussi bien pour le texte que pour les fichiers binaires. La deuxième façon consiste à utiliser f.tell() pour voir si la position de recherche actuelle est à la fin. Si vous voulez que EOF testing ne modifie pas la position actuelle du fichier, vous avez besoin d'un peu de code supplémentaire.

Vous trouverez ci-dessous les deux implémentations.

Utilisation de la méthode tell ()

import os

def is_eof(f):
  cur = f.tell()    # save current position
  f.seek(0, os.SEEK_END)
  end = f.tell()    # find the size of file
  f.seek(cur, os.SEEK_SET)
  return cur == end

Utilisation de la méthode read ()

def is_eof(f):
  s = f.read(1)
  if s != b'':    # restore position
    f.seek(-1, os.SEEK_CUR)
  return s == b''

Comment utiliser ceci

while not is_eof(my_file):
    val = my_file.read(10)

Joue avec ce code .

0
Shital Shah

Bien que j'utilise personnellement une instruction with pour gérer l'ouverture et la fermeture d'un fichier, dans le cas où vous devez lire à partir de stdin et que vous devez suivre une exception EOF, procédez comme suit:

Utilisez try-catch avec EOFError comme exception:

try:
    input_lines = ''
    for line in sys.stdin.readlines():
        input_lines += line             
except EOFError as e:
    print e
0
Blairg23