Python3 filecmp模块测试比较文件原理解析


Posted in Python onMarch 23, 2020

1.filecmp比较文件

filecmp模块提供了一些函数和一个类来比较文件系统上的文件和目录。

1.1 示例数据

使用下面代码创建一组测试文件。

import os
def mkfile(filename, body=None):
  with open(filename, 'w') as f:
    f.write(body or filename)
  return
 
def make_example_dir(top):
  if not os.path.exists(top):
    os.mkdir(top)
  curdir = os.getcwd()
  os.chdir(top)
  os.mkdir('dir1')
  os.mkdir('dir2')
  mkfile('dir1/file_only_in_dir1')
  mkfile('dir2/file_only_in_dir2')
  os.mkdir('dir1/dir_only_in_dir1')
  os.mkdir('dir2/dir_only_in_dir2')
  os.mkdir('dir1/common_dir')
  os.mkdir('dir2/common_dir')
  mkfile('dir1/common_file', 'this file is the same')
  os.link('dir1/common_file', 'dir2/common_file')
  mkfile('dir1/contents_differ')
  mkfile('dir2/contents_differ')
  # Update the access and modification times so most of the stat
  # results will match.
  st = os.stat('dir1/contents_differ')
  os.utime('dir2/contents_differ', (st.st_atime, st.st_mtime))
  mkfile('dir1/file_in_dir1', 'This is a file in dir1')
  os.mkdir('dir2/file_in_dir1')
  os.chdir(curdir)
  return
 
if __name__ == '__main__':
  os.chdir(os.path.dirname(__file__) or os.getcwd())
  make_example_dir('example')
  make_example_dir('example/dir1/common_dir')
  make_example_dir('example/dir2/common_dir')

运行这个脚本会在axample目录下生成一个文件树。

Python3 filecmp模块测试比较文件原理解析

common_dir目录下也有同样的目录结构,以提供有意思的递归比较选择。

1.2 比较文件

cmp()用于比较文件系统上的两个文件。

import filecmp
print('common_file  :', end=' ')
print(filecmp.cmp('example/dir1/common_file',
         'example/dir2/common_file',
         shallow=True),
   end=' ')
print(filecmp.cmp('example/dir1/common_file',
         'example/dir2/common_file',
         shallow=False))
print('contents_differ:', end=' ')
print(filecmp.cmp('example/dir1/contents_differ',
         'example/dir2/contents_differ',
         shallow=True),
   end=' ')
print(filecmp.cmp('example/dir1/contents_differ',
         'example/dir2/contents_differ',
         shallow=False))
print('identical   :', end=' ')
print(filecmp.cmp('example/dir1/file_only_in_dir1',
         'example/dir1/file_only_in_dir1',
         shallow=True),
   end=' ')
print(filecmp.cmp('example/dir1/file_only_in_dir1',
         'example/dir1/file_only_in_dir1',
         shallow=False))

shallo参数告诉cmp()除了文件的元数据外,是否还要查看文件的内容。默认情况下,会使用由os.stat()得到的信息来完成一个浅比较。如果结果是一样的,则认为文件相同。因此,对于同时创建的相同大小的文件,即使他们的内容不同,也会报告为是相同的文件。当shallow为False时,则要比较文件的内容。

Python3 filecmp模块测试比较文件原理解析

如果非递归的比较两个目录中的一组文件,则可以使用cmpfiles()。参数是目录名和两个位置上要检查的我就爱你列表。传入的公共文件列表应当只包含文件名(目录会导致匹配不成功),而且这些文件在两个位置上都应当出现。下一个例子显示了构造公共列表的一种简单方法。与cmp()一样,这个比较也有一个shallow标志。

import filecmp
import os
# Determine the items that exist in both directories
d1_contents = set(os.listdir('example/dir1'))
d2_contents = set(os.listdir('example/dir2'))
common = list(d1_contents & d2_contents)
common_files = [
  f
  for f in common
  if os.path.isfile(os.path.join('example/dir1', f))
]
print('Common files:', common_files)
# Compare the directories
match, mismatch, errors = filecmp.cmpfiles(
  'example/dir1',
  'example/dir2',
  common_files,
)
print('Match    :', match)
print('Mismatch  :', mismatch)
print('Errors   :', errors)

cmpfiles()返回3个文件名列表,分别包含匹配的文件、不匹配的文件和不能比较的文件(由于权限问题或出于其他原因)。

Python3 filecmp模块测试比较文件原理解析

1.3 比较目录

前面介绍的函数适合完成相对简单的比较。对于大目录树的递归比较或者更完整的分析,dircmp类很更有用。在最简单的用例中,report()会打印比较两个目录的报告。

import filecmp
dc = filecmp.dircmp('example/dir1', 'example/dir2')
dc.report()

输出是一个纯文本报告,显示的结果只包括给定目录的内容,而不会递归比较其子目录。在这里,认为文件not_the_same是相同的,因为这里没有比较内容。无法让dircmp像cmp()那样比较文件的内容。

Python3 filecmp模块测试比较文件原理解析

为了更多的细节,也为了完成一个递归比较,可以使用report_full_closure()。

import filecmp
dc = filecmp.dircmp('example/dir1', 'example/dir2')
dc.report_full_closure()

输出将包括所有同级子目录的比较。

Python3 filecmp模块测试比较文件原理解析

1.4 在程序中使用差异

除了生成打印报告,dircmp还能计算文件列表,可以在程序中直接使用。以下各个属性只在请求时才计算,所以对于未用的数据,创建dircmp实例不会带来开销。

import filecmp
import pprint
dc = filecmp.dircmp('example/dir1', 'example/dir2')
print('Left:')
pprint.pprint(dc.left_list)
print('\nRight:')
pprint.pprint(dc.right_list)

所比较目录中包含的文件和子目录分别列在left_list和right_list中。

Python3 filecmp模块测试比较文件原理解析

可以向构造函数传入一个要忽略的名字列表(该列表中指定的名字将被忽略)来对输入进行过滤。默认的,RCS、CVS和tags等名字会被忽略。

import filecmp
import pprint
dc = filecmp.dircmp('example/dir1', 'example/dir2',
          ignore=['common_file'])
print('Left:')
pprint.pprint(dc.left_list)
print('\nRight:')
pprint.pprint(dc.right_list)

在这里,将common_file从要比较的文件列表中去除。

Python3 filecmp模块测试比较文件原理解析

两个输入目录中共有的文件名会保存在common内,各目录独有的文件会列在left_only和right_only中。

import filecmp
import pprint
dc = filecmp.dircmp('example/dir1', 'example/dir2')
print('Common:')
pprint.pprint(dc.common)
print('\nLeft:')
pprint.pprint(dc.left_only)
print('\nRight:')
pprint.pprint(dc.right_only)

"左"目录是dircmp()的第一个参数,"右"目录是第二个参数。

Python3 filecmp模块测试比较文件原理解析

公共成员可以被进一步分解为文件、目录和“有趣”元素(两个目录中类型不同的内容,或者os.stat()指出的有错误的地方)。

import filecmp
import pprint
dc = filecmp.dircmp('example/dir1', 'example/dir2')
print('Common:')
pprint.pprint(dc.common)
print('\nDirectories:')
pprint.pprint(dc.common_dirs)
print('\nFiles:')
pprint.pprint(dc.common_files)
print('\nFunny:')
pprint.pprint(dc.common_funny)

在示例数据中,file_in_dir1元素在一个目录中是一个文件,而在另一个目录中是一个子目录,所以它会出现在“有趣”列表中。

Python3 filecmp模块测试比较文件原理解析

文件之间的差别也可以做类似的划分。

import filecmp
dc = filecmp.dircmp('example/dir1', 'example/dir2')
print('Same   :', dc.same_files)
print('Different :', dc.diff_files)
print('Funny   :', dc.funny_files)

文件not_the_same通过os.stat()比较,并且不检查内容,所以它包含在same_files列表中。

Python3 filecmp模块测试比较文件原理解析

最后一点,子目录也会被保存,以便容易地完成递归比较。

import filecmp
dc = filecmp.dircmp('example/dir1', 'example/dir2')
print('Subdirectories:')
print(dc.subdirs)

属性subdirs是一个字典,它将目录名映射到新的dircmp对象。

Python3 filecmp模块测试比较文件原理解析

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python splitlines使用技巧
Sep 06 Python
python实现基于两张图片生成圆角图标效果的方法
Mar 26 Python
python实现判断数组是否包含指定元素的方法
Jul 15 Python
Python实现的RSS阅读器实例
Jul 25 Python
python距离测量的方法
Mar 06 Python
Python3 使用cookiejar管理cookie的方法
Dec 28 Python
Python动态赋值的陷阱知识点总结
Mar 17 Python
Python pandas.DataFrame 找出有空值的行
Sep 09 Python
python pyenv多版本管理工具的使用
Dec 23 Python
python yield和Generator函数用法详解
Feb 10 Python
django下创建多个app并设置urls方法
Aug 02 Python
实例讲解Python中sys.argv[]的用法
Jun 03 Python
python实现遍历文件夹图片并重命名
Mar 23 #Python
Python3 mmap内存映射文件示例解析
Mar 23 #Python
Python3 io文本及原始流I/O工具用法详解
Mar 23 #Python
python实现横向拼接图片
Mar 23 #Python
Python操作Excel工作簿的示例代码(\*.xlsx)
Mar 23 #Python
python实现拼接图片
Mar 23 #Python
python使用PIL剪切和拼接图片
Mar 23 #Python
You might like
php 动态添加记录
2009/03/10 PHP
php park、unpark、ord 函数使用方法(二进制流接口应用实例)
2010/10/19 PHP
php中利用str_pad函数生成数字递增形式的产品编号
2013/09/30 PHP
php5.2 Json不能正确处理中文、GB编码的解决方法
2014/03/28 PHP
CI框架常用经典操作类总结(路由,伪静态,分页,session,验证码等)
2016/11/21 PHP
php常用数组array函数实例总结【赋值,拆分,合并,计算,添加,删除,查询,判断,排序】
2016/12/07 PHP
thinkphp3.2.0 setInc方法 源码全面解析
2018/01/29 PHP
PHP实现微信提现功能
2018/09/30 PHP
Laravel框架实现多个视图共享相同数据的方法详解
2019/07/09 PHP
Laravel框架Blade模板简介及模板继承用法分析
2019/12/03 PHP
js querySelector() 使用方法
2016/12/21 Javascript
JS实现经典的中国地区三级联动下拉菜单功能实例【测试可用】
2017/06/06 Javascript
JS实现留言板功能
2017/06/17 Javascript
基于es6三点运算符的使用方法(实例讲解)
2017/10/12 Javascript
javascript使用正则实现去掉字符串前面的所有0
2018/07/23 Javascript
解决vuecli3.0热更新失效的问题
2018/09/19 Javascript
js打开word文档预览操作示例【不是下载】
2019/05/23 Javascript
[05:24]TI9采访——教练
2019/08/24 DOTA
[01:07:34]DOTA2-DPC中国联赛定级赛 RNG vs Aster BO3第二场 1月9日
2021/03/11 DOTA
Python numpy.array()生成相同元素数组的示例
2018/11/12 Python
推荐值得学习的12款python-web开发框架
2020/08/10 Python
matplotlib设置颜色、标记、线条,让你的图像更加丰富(推荐)
2020/09/25 Python
意大利综合购物网站:Giordano Shop
2016/10/21 全球购物
联想加拿大官方网站:Lenovo Canada
2018/04/05 全球购物
党员公开承诺书
2014/03/25 职场文书
精神文明单位申报材料
2014/05/02 职场文书
反邪教宣传工作方案
2014/05/07 职场文书
环境整治工作方案
2014/05/18 职场文书
安全生产标语
2014/06/06 职场文书
会展策划与管理专业求职信
2014/06/09 职场文书
暑期培训班策划方案
2014/08/26 职场文书
2015年护理工作总结范文
2015/04/03 职场文书
诚信考试承诺书范文
2015/04/29 职场文书
优质护理心得体会
2016/01/22 职场文书
win10更新失败无限重启解决方法
2022/04/19 数码科技
MySQ InnoDB和MyISAM存储引擎介绍
2022/04/26 MySQL