Python标准库(3)—filecmp

Python017

Python标准库(3)—filecmp,第1张

filecmp模块用来比较目录、文件是否相同。举例如下:

构建两个文件夹,其结构如图所示:

其中data内容保持一致,data1内容不一致,data2是tmp独有,readme1和readme内容一致。

如果单纯比较两个文件是否相同,可以通过filecmp.cmp(f1, f2, shallow=True)实现。其中f1、f2是文件名,shallow=True,则通过文件的元信息比较是否一致,如果是False,则比较两个文件内容。

如果非递归比较两个目录中的一组文件,可以选择通过filecmp.cmpfiles(dir1, dir2, common, shallow=True)实现。其中dir1、dir2是两个文件夹,common是list,里面是需要比较的共同文件名称。

对于大目录树的递归比较或者更完整的分析,可以选择使用dircmp类。

整体效果:

import hashlib

import os

import sys

if len(sys.argv) <3:#1

print("You need to specify two directories:")#1

print(sys.argv[0], "<directory 1><directory 2>")#1

sys.exit() #1

directory1 = sys.argv[1] #2

directory2 = sys.argv[2] #2

print("Comparing:")

print(directory1)

print(directory2)

for directory in [directory1, directory2]:

if not os.access(directory, os.F_OK):

print(directory, "is not a valid directory!")

sys.exit()

def md5(file_path):

if os.path.isdir(file_path):

return '1'

read_file = open(file_path,'r')

the_hash = hashlib.md5()

for line in read_file.readlines():

the_hash.update(line.encode('utf8'))

read_file.close()

return the_hash.hexdigest()

def directory_listing(directory_name):

dir_file_list = {}

dir_root = None

dir_trim = 0

for path, dirs, files in os.walk(directory_name):

if dir_root is None:

dir_root = path

dir_trim = len(dir_root)

print("dir", directory_name,)

print("root is", dir_root)

trimmed_path = path[dir_trim:]

if trimmed_path.startswith(os.path.sep):

trimmed_path = trimmed_path[1:]

#print "path is", path, " and trimmed_path is", trimmed_path

for each_file in files + dirs:

file_path = os.path.join(trimmed_path, each_file)

dir_file_list[file_path] = True

return (dir_file_list, dir_root)

dir1_file_list, dir1_root = directory_listing(directory1)

dir2_file_list, dir2_root = directory_listing(directory2)

results = {}

for file_path in dir2_file_list.keys():

if file_path not in dir1_file_list:

results[file_path] = "not found in directory 1"

else:

#print file_path, "found in directory 1 and 2"

file1 = os.path.join(dir1_root, file_path)

file2 = os.path.join(dir2_root, file_path)

if md5(file1) != md5(file2):

results[file_path] = "is different in directory 2"

else:

results[file_path] = "is the same in both"

for file_path, value in dir1_file_list.items():

if file_path not in results:

results[file_path] = "not found in directory 2"

for path, result in sorted(results.items()):

print(path, result)

Python splitlines()按照行('\r', '\r\n', \n')分隔,返回一个包含各行作为元素的列表,如果参数 keepends 为 False,不包含换行符,如果为 True,则保留换行符。

用的是Python difflib模块:difflib是 Python 提供的比较序列(string list)差异的模块。

实现了三个类:

1>SequenceMatcher 任意类型序列的比较 (可以比较字符串)

2>Differ 对字符串进行比较

3>HtmlDiff 将比较结果输出为html格式.