Outils pour utilisateurs

Outils du site


comparefichiers

Ceci est une ancienne révision du document !


Test de comparaison du contenu de 2 fichiers

Objectif

Dire si 2 fichiers ont le même contenu, sans tenir compte des dates ni des autres propriétés (à part la longueur, bien entendu).

Code proposé

#!/usr/bin/python
# -*- coding: utf-8 -*-
 
import os
 
def compfichiers(nf1, nf2, lgbuf=32*1024):
    """Compare les 2 fichiers et renvoie True seulement s'ils ont un contenu identique"""
    f1 = f2 = None
    try:
        result = False
        # si leur longueur est différente, renvoie False
        if os.path.getsize(nf1)!=os.path.getsize(nf2):
            return result
        # compare les contenus
        f1 = open(nf1, "rb")
        f2 = open(nf2, "rb")
        while True:
            buf1 = f1.read(lgbuf)
            if len(buf1)==0:
                result = True
                break
            buf2 = f2.read(lgbuf)
            if buf1!=buf2:
                break
        f1.close()
        f2.close()
    except:
        if f1!=None:
            f1.close()
        if f2!=None:
            f2.close()
        raise IOError
    return result


Les 2 arguments nf1 et nf2 doivent être des noms de fichiers complets avec leur chemin.

Je n'ai pas essayé, mais a priori, le code devrait être multi-plateforme.

Cette fonction renvoie 3 résultats possibles:

  • True si les contenus sont identiques
  • False s'ils ne le sont pas
  • Une exception si une erreur est intervenue (ouverture, lecture, fermeture)

Voilà comment on y fait appel dans ces 3 cas:

if __name__ == "__main__":
 
    import time
 
    # 1er cas: les 2 fichiers sont identiques 
    nf1 = r"C:\Python25\DLLs\tk84.dll"
    nf2 = r"C:\Python25\DLLs\tk84_idem.dll"
 
    try:
        t = time.clock()
        result = compfichiers(nf1, nf2)
        t = time.clock()-t
        print u"Résultat:", result, "%.3f s" % t
    except:
        t = time.clock()-t
        print u"Résultat: Erreur", "%.3f s" % t
 
 
    # 2ème cas: les 2 fichiers sont différents 
    nf1 = r"C:\Python25\DLLs\tk84.dll"
    nf2 = r"C:\Python25\DLLs\unicodedata.pyd"
    try:
        t = time.clock()
        result = compfichiers(nf1, nf2)
        t = time.clock()-t
        print u"Résultat:", result, "%.3f s" % t
    except:
        t = time.clock()-t
        print u"Résultat: Erreur", "%.3f s" % t
 
    # 3ème cas: le second fichier n'existe pas
    nf1 = r"C:\Python25\DLLs\tk84.dll"
    nf2 = r"C:\Python25\DLLs\cefichiernexistepas.$$$"
    try:
        t = time.clock()
        result = compfichiers(nf1, nf2)
        t = time.clock()-t
        print u"Résultat:", result, "%.3f s" % t
    except:
        t = time.clock()-t
        print u"Résultat: Erreur", "%.3f s" % t


Ce qui donne bien les résultas attendus (avec la durée en secondes):

Résultat: True 0.004 s
Résultat: False 0.000 s
Résultat: Erreur 0.000 s


Le résultat est renvoyé très rapidement, le plus lent étant la comparaison entre 2 fichiers identiques (c'est normal: il faut tout lire!). Mais ici, on a obtenu le résultat “True” en 4 millisecondes avec 2 fichiers identiques d'1Mo chacun.

Avec des fichiers beaucoup plus gros, ça se gâte un peu: avec 4.24Go (c'est l'image iso d'un DVD linux), la réponse demande 3 minutes.

Les solutions passant par la comparaison de résultats de hashage ne sont pas plus rapides (il faut tout de même lire les 2 fichiers pour cela!). De plus, l'égalité des empreintes hash des 2 fichiers ne donne pas la garantie absolue que les 2 contenus sont identiques.


Amusez-vous bien!

comparefichiers.1237215069.txt.gz · Dernière modification: 2009/03/16 15:51 de tyrtamos

Outils de la page