Есть ли в Python сжатый способ сравнения одинакового содержимого двух текстовых файлов? - PullRequest
44 голосов
/ 31 октября 2008

Мне все равно, в чем различия. Я просто хочу знать, отличается ли содержимое.

Ответы [ 8 ]

60 голосов
/ 31 октября 2008

Низкоуровневый путь:

from __future__ import with_statement
with open(filename1) as f1:
   with open(filename2) as f2:
      if f1.read() == f2.read():
         ...

Способ высокого уровня:

import filecmp
if filecmp.cmp(filename1, filename2, shallow=False):
   ...
23 голосов
/ 31 октября 2008

Если вам нужна даже базовая эффективность, вы, возможно, захотите сначала проверить размер файла:

if os.path.getsize(filename1) == os.path.getsize(filename2):
  if open('filename1','r').read() == open('filename2','r').read():
    # Files are the same.

Это спасает вас от чтения каждой строки двух файлов, которые даже не имеют одинаковый размер и, следовательно, не могут быть одинаковыми.

(Более того, вы можете вызвать быструю сумму MD5 каждого файла и сравнить их, но это не "в Python", поэтому я остановлюсь здесь.)

9 голосов
/ 01 ноября 2008

Это функция сравнения файлов в функциональном стиле. Он сразу возвращает False, если файлы имеют разные размеры; в противном случае, он читает в блоках размером 4 КБ и мгновенно возвращает значение False при первой разнице:

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])

Просто другой дубль:)

6 голосов
/ 31 октября 2008

Поскольку я не могу комментировать ответы других, я напишу свои.

Если вы используете md5, вы определенно должны не просто md5.update (f.read ()), так как вы будете использовать слишком много памяти.

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()
3 голосов
/ 31 октября 2008

f = open(filename1, "r").read()
f2 = open(filename2,"r").read()
print f == f2


2 голосов
/ 31 октября 2008

Я бы использовал хеш содержимого файла, используя 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!'
2 голосов
/ 31 октября 2008

Для больших файлов вы можете вычислить хэш MD5 или SHA файлов.

1 голос
/ 15 декабря 2016
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"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...