Outils pour utilisateurs

Outils du site


nblignes_fichier

Obtenir le nombre de lignes d'un fichier texte sans les relire

Objectif

Obtenir le nombre de lignes d'un fichier texte nécessite classiquement de les lire toutes pour les compter.

On va utiliser un autre principe: lire le fichier par blocs binaires, et compter le nombre de caractères de fin de ligne ('\n' par défaut).

Code proposé

def nblignes(nf, fdl='\n', tbuf=16384):
    """Compte le nombre de lignes du fichier nf"""
    c = 0
    f = open(nf, 'rb')
    while True:
        buf = None
        buf = f.read(tbuf)
        if len(buf)==0:
            break
        c += buf.count(fdl)
    f.seek(-1, 2)
    car = f.read(1)
    if car != fdl:
        c += 1
    f.close()
    return c    

Il y a une petite subtilité: il est possible que la dernière ligne de texte ne soit pas terminée par un caractère de fin de ligne. Auquel cas, dans un éditeur de texte, le curseur resterait à la fin de la dernière ligne en refusant de passer à la ligne vide suivante. Mais comme c'est tout de même une ligne de texte, il faut la compter. C'est ce que fait la dernière partie du code commençant par f.seek(-1, 2).

Application. Fabriquons un fichier texte de 50000 lignes:

nf = 'test.txt'
f = open(nf, 'w')
for i in xrange(0,50000):
    x = "%d" % (i)
    f.write(x + '\n')
f.close    

Et comptons le nombre de ligne de ce fichier:

print nblignes(nf)
50000

Et si on fait en sorte que la dernière ligne ne comporte pas de fin de ligne:

nf = 'test.txt'
f = open(nf, 'w')
for i in xrange(0,49999):
    x = "%d" % (i)
    f.write(x + '\n')
x = "%d" % (49999)
f.write(x)
f.close    

Le comptage du nombre de lignes donne le même résultat:

print nblignes(nf)
50000

Est-ce que c'est rapide? Assez, oui:

Sur un fichier de 1000000 (1 million) de lignes et 7,7 Mo, le nombre de lignes est obtenu en 10 fois moins de temps par cette méthode par rapport à la méthode de lecture texte de toutes les lignes. Et en plus, on consomme beaucoup moins de place mémoire puisque les blocs lus prennent la même place mémoire (on le vérifie par id(buf)) et donc ne la fragmente pas.


Amusez-vous bien!

nblignes_fichier.txt · Dernière modification: 2010/03/27 19:59 par tyrtamos

Outils de la page