如何在Python中检查两个文件(字符串和文件)是否具有相同的内容?

时间:2011-08-05 23:25:26

标签: python python-3.x

我对Python很陌生并且有疑问。如何在Python中检查两个文件(字符串和文件)是否具有相同的内容?我需要下载一些东西并重命名,但我不想保存两个或更多不同名称的相同东西(相同的东西可以在不同的IP地址)。

6 个答案:

答案 0 :(得分:5)

如果文件很大,我会考虑以这样的方式阅读:

compare.py:

import hashlib

teststr = "foo"
filename = "file.txt"

def md5_for_file(f, block_size=2**20):
    md5 = hashlib.md5()
    while True:
        data = f.read(block_size)
        if not data:
            break
        md5.update(data.encode('utf8'))
    return md5.digest()


md5 = hashlib.md5()
md5.update((teststr + "\n").encode('utf8'))
digest = md5.digest()
f = open(filename, 'r')
print(md5_for_file(f) == digest)

file.txt的:

foo

如果字符串和文件匹配

,则此程序打印为True

答案 1 :(得分:4)

使用文件内容的sha1哈希。

#!/usr/bin/env python
from __future__ import with_statement
from __future__ import print_function

from hashlib import sha1

def shafile(filename):
    with open(filename, "rb") as f:
        return sha1(f.read()).hexdigest()

if __name__ == '__main__':
    import sys
    import glob
    globber = (filename for arg in sys.argv[1:] for filename in glob.glob(arg))
    for filename in globber:
        print(filename, shafile(filename))

此程序在命令行中使用通配符,但它仅用于演示目的。

答案 2 :(得分:2)

如果你想要的只是一个校验和,那么使用哈希是不必要。 Python在binascii module中有一个校验和。

binascii.crc32(data[, crc])

答案 3 :(得分:1)

最好的方法是获得一些哈希值(即md5)并进行比较。

Here你可以阅读如何获取文件的md5。

答案 4 :(得分:1)

您下载的每个文件都会生成哈希或校验和。保留这些哈希/校验和的列表。

然后在将下载的数据保存到磁盘之前,检查列表中是否已存在哈希/校验和,如果存在,则不保存,但如果不存储,则保存文件并添加校验和/哈希到列表。

伪代码:

checksums = []
for url in all_urls:
    data = download_file(url)
    checksum = make_checksum(data)
    if checksum not in checksums:
         save_to_file(data)
         checksums.append(checksum)

答案 5 :(得分:1)

虽然散列和校验和非常适合比较文件列表,但如果您只是比较两个特定文件而没有预先计算的散列/校验和,那么直接比较两个文件比它更快为每个计算哈希/校验和并比较哈希/校验和

def equalsFile(firstFile, secondFile, blocksize=65536):
    buf1 = firstFile.read(blocksize)
    buf2 = secondFile.read(blocksize)
        while len(buf1) > 0:
        if buf1!=buf2:
            return False
        buf1, buf2 = firstFile.read(blocksize), secondFile.read(blocksize)
    return True

在我的测试中,64 md5检查两个50MB文件在24.468秒内完成,而64个直接比较仅在4.770秒内完成。此方法还具有在找到任何差异时立即返回false的优点,而计算哈希值必须继续读取整个文件。

在不同的文件上创建早期失败的另一种方法是在使用os.path.getsize(filename)运行上述测试之前检查其大小。在检查具有不同内容的两个文件的相等性时,这种大小差异非常常见,因此应始终首先检查。

import os
if os.path.getSize('file1.txt') != os.path.getSize('file2.txt'):
    print 'false'
else:
    print equalsFile(open('file1.txt', 'rb'), open('file1.txt', 'rb'))