为什么重复文件会得到不同的哈希值?

问题描述 投票:0回答:1

我需要检查包含数百万个文件的文件夹中是否存在重复和损坏的文件。

首先,我正在尝试这种方式:

hash_files = pd.DataFrame({"Path":[],
                           "Hash":[]})

rootdir = "//?/Z:/"

error_files = []
for root, subdir, files in os.walk(rootdir):
    print(root)
    for filename in files:

        # String with file path
        source = root + "/" + filename

        with open(source, "rb") as file_obj:
            
            # File reading
            file_contents = file_obj.read() 
            file_obj.close()
            
        # Hash identification
        md5_hash = hashlib.blake2b(file_contents).hexdigest() 
        
        hash_files.loc[len(hash_files) + 1] = [source, md5_hash]

但是文件读取部分在大文件(而且有很多)中运行花费的时间太长。所以我尝试了另一种似乎更快的方法:

hash_files = pd.DataFrame({"Path":[],
                           "Hash":[]})

rootdir = "//?/Z:/"

error_files = []
for root, subdir, files in os.walk(rootdir):
    print(root)
    for filename in files:

        # String with file path
        source = root + "/" + filename  
            
        # Hash identification
        md5_hash = hashlib.blake2b(source.encode('utf-8')).hexdigest()
        
        hash_files.loc[len(hash_files) + 1] = [source, md5_hash]

但是在最后一种方式中,我得到了重复文件的不同哈希值,并且我认为它们必须是相同的。

有人知道出了什么问题或者我如何才能以更快的方式获得所有这些文件的正确哈希值?

python hash md5 hashlib
1个回答
0
投票

这是多处理的一个很好的例子。

子进程应该计算哈希值并返回路径和十六进制摘要。

这样的事情可能会尽可能快地完成:

from hashlib import blake2b
from multiprocessing import Pool
from pathlib import Path, PosixPath
from typing import Iterator

CHUNK = 64 * 1024
SRCDIR = Path("/Users/CtrlZ")

def process(path: PosixPath) -> tuple[PosixPath, str]:
    h = blake2b()
    with open(path, "rb") as f:
        while b := f.read(CHUNK):
            h.update(b)
    return path, h.hexdigest()

def getfiles(d: Path) -> Iterator:
    for e in d.iterdir():
        if e.is_file():
            yield e

def main():
    with Pool() as pool:
        result =  pool.map_async(process, getfiles(SRCDIR))
        for p, h in result.get():
            print(p, h)


if __name__ == "__main__":
    main()
© www.soinside.com 2019 - 2024. All rights reserved.