En Python, existe-t-il un moyen concis de comparer si le contenu de deux fichiers texte est identique?
Question
Je me moque des différences. Je veux juste savoir si le contenu est différent.
La solution
Le niveau bas:
from __future__ import with_statement
with open(filename1) as f1:
with open(filename2) as f2:
if f1.read() == f2.read():
...
La méthode de haut niveau:
import filecmp
if filecmp.cmp(filename1, filename2, shallow=False):
...
Autres conseils
Si vous visez une efficacité même élémentaire, vous voudrez probablement d'abord vérifier la taille du fichier:
if os.path.getsize(filename1) == os.path.getsize(filename2):
if open('filename1','r').read() == open('filename2','r').read():
# Files are the same.
Ceci vous évite de lire chaque ligne de deux fichiers qui ne sont même pas de la même taille et qui ne peuvent donc pas être identiques.
(Même plus loin, vous pouvez appeler un fichier MD5 rapide de chaque fichier et comparer ceux-ci, mais ce n'est pas "en Python", alors je vais m'arrêter ici.)
Il s'agit d'une fonction de comparaison de fichiers de style fonctionnel. Il retourne instantanément False si les fichiers ont des tailles différentes; sinon, il lit en tailles de bloc de 4 Ko et renvoie False instantanément à la première différence:
from __future__ import with_statement
import os
import itertools, functools, operator
def filecmp(filename1, filename2):
"Do the two files have exactly the same contents?"
with open(filename1, "rb") as fp1, open(filename2, "rb") as fp2:
if os.fstat(fp1.fileno()).st_size != os.fstat(fp2.fileno()).st_size:
return False # different sizes ∴ not equal
fp1_reader= functools.partial(fp1.read, 4096)
fp2_reader= functools.partial(fp2.read, 4096)
cmp_pairs= itertools.izip(iter(fp1_reader, ''), iter(fp2_reader, ''))
inequalities= itertools.starmap(operator.ne, cmp_pairs)
return not any(inequalities)
if __name__ == "__main__":
import sys
print filecmp(sys.argv[1], sys.argv[2])
Juste une prise différente:)
Comme je ne peux pas commenter les réponses des autres, j'écrirai les miennes.
Si vous utilisez md5, vous ne devez absolument pas simplement md5.update (f.read ()), car vous utiliserez trop de mémoire.
def get_file_md5(f, chunk_size=8192):
h = hashlib.md5()
while True:
chunk = f.read(chunk_size)
if not chunk:
break
h.update(chunk)
return h.hexdigest()
f = open(filename1, "r").read()
f2 = open(filename2,"r").read()
print f == f2
J'utiliserais un hachage du contenu du fichier avec MD5.
import hashlib
def checksum(f):
md5 = hashlib.md5()
md5.update(open(f).read())
return md5.hexdigest()
def is_contents_same(f1, f2):
return checksum(f1) == checksum(f2)
if not is_contents_same('foo.txt', 'bar.txt'):
print 'The contents are not the same!'
from __future__ import with_statement
filename1 = "G:\\test1.TXT"
filename2 = "G:\\test2.TXT"
with open(filename1) as f1:
with open(filename2) as f2:
file1list = f1.read().splitlines()
file2list = f2.read().splitlines()
list1length = len(file1list)
list2length = len(file2list)
if list1length == list2length:
for index in range(len(file1list)):
if file1list[index] == file2list[index]:
print file1list[index] + "==" + file2list[index]
else:
print file1list[index] + "!=" + file2list[index]+" Not-Equel"
else:
print "difference inthe size of the file and number of lines"