使用Python查找重复文件
复制文件在我们电脑上积累信息时会占用额外的硬盘空间,这是一个常见的现象,因此,手动查找和删除重复文件既费时又费力;幸运的是,我们可以使用Python自动化这个过程,在本教程中,我们将学习如何使用一个简短的脚本实现这一点。
设置
在本教程中,我们将使用Python中内置的`os`和`hashlib`模块,因此无需安装任何额外的软件包。
import os import hashlib
算法
创建一个名为`hashfile()`的函数,该函数使用SHA-1算法为文件生成唯一的哈希值,它接受文件名作为输入并返回哈希值。
定义`find_duplicates()`方法,允许搜索特定目录中的重复文件;它生成一系列列表,每个参数(例如目录名)都包含重复文件的路径。
在`find_duplicates()`方法内部,将每个目录文件的哈希值存储在一个字典中,并使用`hashfile()`方法迭代计算每个目录文件的哈希值。
如果哈希值已存在于字典中,则将文件路径添加到重复文件的列表中。否则,字典将添加哈希值和文件路径。
由于这些内部列表实际上不包含重复文件路径,因此将它们过滤掉。
示例
import os import hashlib def hashfile(filename): with open(filename, 'rb') as f: hasher = hashlib.sha1() while True: data = f.read(1024) if not data: break hasher.update(data) return hasher.hexdigest()
这段代码使用Python的`hashlib`模块创建`hashfile()`方法,上述方法返回文件的SHA-1哈希值,并接受文件名作为输入。当一次读取文件的1024个字节时,该函数会修改每个块的哈希值。该函数在读取完整个文件后,返回哈希值的`hexdigest`作为字符串。
def find_duplicates(dirname): files = os.listdir(dirname) if len(files) < 2: return hashes = {} for filename in files: path = os.path.join(dirname, filename) if not os.path.isfile(path): continue file_hash = hashfile(path) if file_hash not in hashes: hashes[file_hash] = path else: print(f'Duplicate found: {path} and {hashes[file_hash]}')
这段代码中的`find_duplicates()`方法定义了一个列表列表,其中包含重复文件的路径,并接受目录名作为输入。该函数创建一个空的重复列表和一个空的字典文件,分别用于存储重复文件的路径和目录中每个文件的哈希值。使用`os.listdir()`方法,代码迭代目录中的每个文件,并使用`os.path.isfile()`函数确定它是否是一个文件。
该函数使用前面定义的`hashfile()`函数为每个文件创建一个哈希值,并检查哈希值是否已存在于文件的字典中。如果哈希值已存在,则该函数将当前文件路径和具有相同哈希值的先前文件的路径添加到重复列表中。该函数最终返回所有找到的重复文件的列表。
最后调用该方法以运行整个脚本 -
if __name__ == '__main__': show_duplicates('.')
解释
因此,整个代码可以写成 -
import os import hashlib def hashfile(filename): with open(filename, 'rb') as f: hasher = hashlib.sha1() while True: data = f.read(1024) if not data: break hasher.update(data) return hasher.hexdigest() def find_duplicates(dirname): files = os.listdir(dirname) if len(files) < 2: return hashes = {} for filename in files: path = os.path.join(dirname, filename) if not os.path.isfile(path): continue file_hash = hashfile(path) if file_hash not in hashes: hashes[file_hash] = path else: print(f'Duplicate found: {path} and {hashes[file_hash]}') if __name__ == '__main__': show_duplicates('.')
输出
[您可以将多个文件复制粘贴到运行脚本的目录中以获得所需的输出]
Duplicate found: .\DSA-guide-2023.pdf and .\DSA-guide-2023 - Copy.pdf
我们首先导入`os`模块,该模块提供与操作系统交互的方法。
然后定义`find_duplicates`函数,该函数接受一个目录作为输入,并返回在给定目录中找到的所有重复文件的列表。
`hash_dict`变量是将用于存储每个文件哈希值的字典。
`duplicates`变量是一个列表,将存储发现为重复文件的任何文件的路径。
然后,我们使用`os.walk`函数遍历目录及其子目录。
对于目录中的每个文件,我们使用`hash_file`函数来计算其哈希值。
然后,我们检查`hash_dict`字典中是否存在该哈希值。如果存在,则将当前文件的路径和之前具有相同哈希值的文件的路径添加到`duplicates`列表中。如果不存在,则将哈希值和文件路径添加到`hash_dict`字典中。
返回`duplicates`列表,其中包含所有找到的重复文件,并将其打印出来。
结论
即使可能涉及一些开销,识别重复文件对于保持我们系统井井有条至关重要。在这篇文章中,我们展示了如何使用Python的`os`模块和`hashlib`模块来查找目录中重复的文件。`os`模块简化了操作系统通信,而`hashlib`模块允许我们访问文件的哈希值。通过结合这两个模块,我们能够构建“查找重复项”函数,该函数能够在目录中查找重复文件。