Ceci est une ancienne révision du document !
On a plusieurs fichiers de même nom dans 2 répertoires. On veut savoir s'ils ont un contenu identique.
Le résultat est renvoyé sous forme d'une liste de: [nom_de_fichier, resultat], avec resultat:
On peut aussi avoir une exception en cas d'erreur d'entrée/sortie plus importante (l'un des répertoires n'existe pas ou droits insuffisants pour lire leur contenu)
#!/usr/bin/python # -*- coding: utf-8 -*- from __future__ import division import os import fnmatch ############################################################################## def comparefic(nfc1, nfc2, lgbuf=32*1024): """Compare les 2 fichiers et renvoie True ou False selon que leur contenu binaire est identique ou non (la comparaison s'arrête à la 1ère différence). Déclenche une exception à gérer par l'appelant en cas d'erreur de lecture """ f1 = None f2 = None result = False try: if os.path.getsize(nfc1) == os.path.getsize(nfc2): f1 = open(nfc1, "rb") f2 = open(nfc2, "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 ############################################################################## def okselect(nf, selections=["*"], exclusions=[""]): """renvoie si un nom correspond à un motif de selection, sans être interdit par un motif d'exclusion """ for selection in selections: if fnmatch.fnmatch(nf,selection): # on a trouve un motif de selection qui marche for exclusion in exclusions: if fnmatch.fnmatch(nf,exclusion): # mais un motif d'exclusion l'interdit return False return True # une selection marche sans exclusion: c'est ok return False # aucun motif de selection ne marche ############################################################################## def comp(v1,v2): """comparaison alphabétique des chaines de caractères v1 et v2 (unicode): => renvoie un entier <0 si v1<v2 (= v1 est avant v2), => renvoie 0 si v1==v2, => renvoie un entier >0 si v1>v2 (= v1 est après v2) """ alpha = u"aAàÀâÂåÅæÆbBcCçÇdDeEéÉèÈêÊëËfFgGhHiIîÎïÏjJkKlLmMnNñÑoOôÔœŒp" + \ u"PqQrRsStTuUùÙûÛüÜvVwWxXyYÿŸzZ" lgalpha = len(alpha) lg1 = len(v1) lg2 = len(v2) lg = min([lg1,lg2]) # lg=longueur du mot le plus court entre V1 et v2 for i in range(0,lg): i1 = alpha.find(v1[i]) if i1<0: # le caractère i de v1 n'est pas dans alpha i1 = ord(v1[i]) # la comparaison respectera donc l'ordre unicode i2 = alpha.find(v2[i]) if i2<0: # le caractère i de v2 n'est pas dans alpha i2 = ord(v2[i]) # la comparaison respectera donc l'ordre unicode if i1<i2: return -1 if i1>i2: return 1 # ici, les lg 1ers caractères sont ident.: le plus court est avant l'autre return lg1-lg2 ############################################################################## def listefics(rep, selections=["*"], exclusions=[""]): """renvoie la liste de tous les fichiers du répertoire rep correspondant à la sélection-exclusion """ try: entrees = os.listdir(rep) # rep doit avoir le bon encodage except: raise # redéclenche l'exception pour traitement par l'appelant entrees.sort(comp) # tri les noms nfics = [] for entree in entrees: if not os.path.isdir(os.path.join(rep, entree)): if okselect(entree, selections, exclusions): nfics.append(entree) return nfics ############################################################################## def comparefics(rep1, rep2, selections=["*"], exclusions=[""]): """Compare les contenus des fichiers de rep1 qui sont aussi dans rep2""" try: nfics = listefics(rep1, selections, exclusions) except: raise # redéclenche l'exception pour traitement par l'appelant R = [] for nf in nfics: nfc1 = os.path.join(rep1, nf) nfc2 = os.path.join(rep2, nf) if os.path.exists(nfc2): try: res = comparefic(nfc1, nfc2) if res: R.append([nf, True]) else: R.append([nf, False]) except: R.append([nf, None]) else: R.append([nf, "absent"]) return R
Et voilà comment on utilise (comparaison des contenus des fichiers .doc entre les 2 répertoires):
rep1 = r"C:\Users\tyrtamos\chemin1".decode('utf-8') rep2 = r"C:\Users\tyrtamos\chemin2".decode('utf-8') try: R = comparefics(rep1, rep2, ["*.doc"]) for nf, r in R: print nf, r except: print u"erreur d'entrée-sortie"
Ce qui affichera, par exemple:
fichier1.doc True fichier2.doc True fichier3.doc None fichier4.doc False fichier5.doc absent
Amusez-vous bien!