在Python中,是否有一种简洁的方法来比较两个文本文件的内容是否相同?

时间:2008-10-31 17:47:39

标签: python file compare

我不在乎差异是什么。我只是想知道内容是否不同。

9 个答案:

答案 0 :(得分:60)

低级方式:

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):
   ...

答案 1 :(得分:23)

如果你想提高基本效率,你可能想先检查文件大小:

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

这可以节省您读取两个文件大小相同的每一行,因此不能相同。

(更进一步,你可以调用每个文件的快速MD5sum并进行比较,但这不是“在Python中”,所以我会在这里停止。)

答案 2 :(得分:9)

这是一个功能风格的文件比较功能。如果文件大小不同,它立即返回False;否则,它读入4KiB块大小并在第一个差异时立即返回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])

只是一个不同的看法:)

答案 3 :(得分:6)

由于我不能评论别人的答案,我会写自己的。

如果你使用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()

答案 4 :(得分:3)


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


答案 5 :(得分:2)

对于较大的文件,您可以计算文件的MD5SHA哈希值。

答案 6 :(得分:2)

我会使用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!'

答案 7 :(得分:1)

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"

答案 8 :(得分:0)

简单高效的解决方案:

import os


def is_file_content_equal(
    file_path_1: str, file_path_2: str, buffer_size: int = 1024 * 8
) -> bool:
    """Checks if two files content is equal
    Arguments:
        file_path_1 (str): Path to the first file
        file_path_2 (str): Path to the second file
        buffer_size (int): Size of the buffer to read the file
    Returns:
        bool that indicates if the file contents are equal
    Example:
        >>> is_file_content_equal("filecomp.py", "filecomp copy.py")
            True
        >>> is_file_content_equal("filecomp.py", "diagram.dio")
            False
    """
    # First check sizes
    s1, s2 = os.path.getsize(file_path_1), os.path.getsize(file_path_2)
    if s1 != s2:
        return False
    # If the sizes are the same check the content
    with open(file_path_1, "rb") as fp1, open(file_path_2, "rb") as fp2:
        while True:
            b1 = fp1.read(buffer_size)
            b2 = fp2.read(buffer_size)
            if b1 != b2:
                return False
            # if the content is the same and they are both empty bytes
            # the file is the same
            if not b1:
                return True