基础知识
简介
为了保证 留存的文件是我们需要的,所以,我们再保存后的文件,做一个唯一的标识符,然后再次使用的时候,检查文件的位移标识符,如果是一致的,说明文件在这期间没有任何变动,说明安全,否则,说明文件发生异常变动。
工具
filecmp
各种嵌套文件的 信息对比 情况
场景
系统安全
文件变动
备份安全
等
模块详解
模块简介
定位
文件信息的比对
组成
cmp 单文件信息对比
cmpfiles 多文件信息对比
dircmp 目录文件信息对比
单文件对比
基础知识:查看文件的属性
ls 查看文件列表
ll 查看列表的时候,展示属性信息
lsattr 查看文件的一些扩展属性
file 查看文件类型
stat 查看文件状态信息
模块解析:
filecmp.cmp(文件1,文件2,[shallow=True|False])
shallow=True表示使用sys.stat对比文件属性
False表示在True的基础上,增加对内容的比对
注意:
属性的比较,主要以 修改的时间 属性为基准。
准备工作:
文件属性对比:
文件基本属性比较
查看文件后效果比较 - bashrc2
结果显示,cmp对比文件属性,不是以访问时间为对比
修改文件:
多文件对比
方法简介:
filecmp.cmpfiles(目录1,目录2,common[shallow=True|False])
shallow=True 表示 使用sys.stat对比文件属性
False 表示 在True的基础上,增加对内容的比对
注意:
结果相对于cmp来说,不是True和False,而是三个列表,一致的列表、不一致的列表、无法比对列表。
一致的列表 属性一致
不一致的列表 属性不一致
无法比对列表,未知原因导致,无法进行文件比较或者属性获取
目录的状态详情
md5sum命令解析:
md5sum
基于文件的属性(不是内容)信息,生成唯一的标识符,也叫校验码 | 和
准备相同的
多文件比较效果:
目录对比
sudo apt install tree -y
例 tree /tmp/
基础语法
filecmp.dircmp(目录1,目录2,ignore,hide)
ignore 表示可以忽略的对比文件
hide 表示可以隐藏的文件列表
注意:
三种输出结果报告
report 仅当前目录
report_partial_closure 当前目录及下一级子目录
report_all_closure 所有的目录结构
如何批量创建嵌套结构的目录:
mkdir{dir1,dir2,dir3/sub1} -p
创建代码:
mkdir dir1/{a,f1,f2,f3,f4}
mkdir dir1/{a,f1,f2,f3,f4} -p
mkdir dir1/a/{a1,b/{b1,b2,b3}} -p
touch dir1/test.py
mkdir dir2/{a/{a1,b/{b1,b2,b3}},aa/aa1,f1,f2,f3,f5} -p
touch dir2/test.py
简单实践
思路:
1 准备环境(已准备)
2 定制目录比较
2-1 定制目录位置
2-2 实现目录的比对,忽略掉普通文件
3 输出报告
3-1 仅输出当前目录下的效果
dir_object.report()
3-2 仅输出当前目录及一级目录下的效果
dir_object.report_partial_closure()
3-3 输出所有目录信息的效果
dir_object.report_full_closure()
4 查看详情
4-1 查询属性信息
print("左目录:{}".format(dir_object.left))
print("信息格式:{}".format(type(dir_object.left)))
4-2 属性信息查看
print("左目录:{}".format(dir_object.left))
print("右目录:{}".format(dir_object.right))
print("仅左目录:{}".format(dir_object.left_only))
print("仅右目录:{}".format(dir_object.right_only))
print("共同目录:{}".format(dir_object.common))
print("无法比较文件:{}".format(dir_object.funny_files))
综合案例:校验源与备份目录差异
需求简介
简介
文件的同步场景
新文件同步
老文件更新
如果同步失败或者更新失误:
针对性的检查,并进行同步或者更新
思路:
内容的针对性判断 - - filecmp
left_only 项目源目录仅有的 - - 同步失败的新文件
diff_files 项目源目录中内容不一致的 - - 更新失败的文件
内容的复制和同步
shutil.copyfile - - 文件的同步
os.makedir - - 新目录的创建
原则
1 导模块
- - 分析使用了哪些功能模块
2 看方法
- - 看一下主要有哪些业务组成
3 主函数
- - 看一下业务逻辑的流程
代码分析:
思路:
文件对比思路
1 接收两个目录
2 对目录仅简单的比对,并获取失败的内容
3 列表推导式,临时存储一级异常目录
4 递归方式,对子目录进行文件对比测试
5 返回最终的不匹配目录或者文件
主函数代码 - 代码思路:
1 接收脚本执行时候的参数
argv[1]和argv[2]
2 获取所有的源目录结果信息
compareme 方法的使用
3 如果是新目录,则进行创建
属性更改的 目标文件列表
创建对应的目录
4 如果是普通文件,则进行简单复制
将源文件和目标文件组合对
然后使用 copy 的方法创建
代码实践1
应该返回f4
"""
文件备份案例实践
"""
# 导包
import os,sys
import filecmp
import re
import shutil
# 临时的文件列表
hoderlist=[]
# 1 文件比对方法
def compareme(dir1,dir2):
"""
对文件目录进行比对,获取所有的文件信息
:param dir1:源代码目录结构
:param dir2:目标目录结构
:return: hoderlist 返回统计后的文件目录列表
"""
# 1 对两个目录进行比较
dircomp = filecmp.dircmp(dir1,dir2)
# 2 获取需要同步的信息
only_in_one = dircomp.left_only
diff_in_one = dircomp.diff_files
# 3 更新临时存储的文件列表 所在的目录
# 3-1 获取绝对路径
dirpath = os.path.abspath(dir1)
# 3-2 获取左侧唯一的内容
[hoderlist.append(os.path.abspath(os.path.join(dir1,x))) for x in only_in_one]
# 3-3 获取左侧不匹配的内容
[hoderlist.append(os.path.abspath(os.path.join(dir1, x))) for x in diff_in_one]
# 4 递归方式获取所有文件信息
if len(dircomp.common_files) > 0:
# 4-1 遍历所有的子目录
for item in dircomp.common_dirs:
# 4-2 对所有的子目录进行内容比对 - 使用方法本身
compareme(os.path.abspath(os.path.join(dir1,item)),os.path.abspath(os.path.join(dir2,item)))
# 5 返回更新后的文件列表
return hoderlist
# 2 主函数方法
def main():
pass
# 3 执行
if __name__ == '__main__':
# 临时测试 对比 /home/python/dir1 和 /home/python/dir2 返回应该是f4
result = compareme('/home/user1/dir1','/home/user1/dir2')
print("待同步的源目录下的文件有:{}".format(result))
输出结果为
待同步的源目录下的文件有:['/home/user1/dir1/f4']
代码实践2 - 主函数
代码内容
"""
文件备份案例实践
"""
# 导包
import os,sys
import filecmp
import re
import shutil
# 临时的文件列表
hoderlist=[]
# 1 文件比对方法
def compareme(dir1,dir2):
"""
对文件目录进行比对,获取所有的文件信息
:param dir1:源代码目录结构
:param dir2:目标目录结构
:return: hoderlist 返回统计后的文件目录列表
"""
# 1 对两个目录进行比较
dircomp = filecmp.dircmp(dir1,dir2)
# 2 获取需要同步的信息
only_in_one = dircomp.left_only
diff_in_one = dircomp.diff_files
# 3 更新临时存储的文件列表 所在的目录
# 3-1 获取绝对路径
dirpath = os.path.abspath(dir1)
# 3-2 获取左侧唯一的内容
[hoderlist.append(os.path.abspath(os.path.join(dir1,x))) for x in only_in_one]
# 3-3 获取左侧不匹配的内容
[hoderlist.append(os.path.abspath(os.path.join(dir1, x))) for x in diff_in_one]
# 4 递归方式获取所有文件信息
if len(dircomp.common_files) > 0:
# 4-1 遍历所有的子目录
for item in dircomp.common_dirs:
# 4-2 对所有的子目录进行内容比对 - 使用方法本身
compareme(os.path.abspath(os.path.join(dir1,item)),os.path.abspath(os.path.join(dir2,item)))
# 5 返回更新后的文件列表
return hoderlist
# 2 主函数方法
def main():
# 1 准备工作
# 1-1 接收两个脚本参数及脚本的使用方式
if len(sys.argv) > 2:
dir1 = sys.argv[1]
dir2 = sys.argv[2]
else:
print("脚本的使用方式:脚本名 目录1 目录2")
sys.exit()
# 1-2 目录的准备工作
source_files = compareme(dir1,dir2) # 获取待同步的目录
dir1 = os.path.abspath(dir1) # 获取待同步的目录位置
destination_files = [] # 要同步的目录路径
createdir_bool = False # 新增目录的时候,设定的标识符
# 2 目录创建
# 2-1 获取待同步的所有目录结构 - 通过替换的方式实现目标目录的确定
# 这是已存在的目录内容同步
for item in source_files:
# 目标目录的列表同步
destination_dir = re.sub(dir1,dir2,item)
destination_files.append(destination_dir)
# 对目标目录进行简单的判断,如果不存在就创建
if os.path.isdir(item):
if not os.path.exists(destination_dir):
os.makedirs(destination_dir)
createdir_bool = True
# 2-2 同步目录 - 必须保证临时目录createdir_bool是True
# 这是刚才新建的目录内容同步
if createdir_bool:
destination_files = []
source_files = []
source_files = compareme(dir1,dir2)
for item in source_files:
destination_dir = re.sub(dir1,dir2,item)
destination_files.append(destination_dir)
# 3 文件的同步
# 3-1 提示同步更新
print("更新item:")
print("需要同步的文件:{}".format(source_files))
# 3-2 便于cp命令的实现,我们将源文件路径和目标文件路径生成数据对
copy_pair = zip(source_files,destination_files)
# 3-3 开始进行数据的复制
for item in copy_pair:
if os.path.islife(item[0]):
shutil.copyfile(item[0],item[1])
# 样式:cp file1 file2
# 3 执行
if __name__ == '__main__':
main()
实践1 - 脚本的使用 (不给参数,直接run)
实践2 - 目录的同步创建
rm -r /home/user1/dir2/f4
使用pycharm执行命令的时候 添加执行参数,两个参数中间必须加空格!:
"""
文件备份案例实践
"""
# 导包
import os,sys
import filecmp
import re
import shutil
# 临时的文件列表
hoderlist=[]
# 1 文件比对方法
def compareme(dir1,dir2):
"""
对文件目录进行比对,获取所有的文件信息
:param dir1:源代码目录结构
:param dir2:目标目录结构
:return: hoderlist 返回统计后的文件目录列表
"""
# 1 对两个目录进行比较
dircomp = filecmp.dircmp(dir1,dir2)
# 2 获取需要同步的信息
only_in_one = dircomp.left_only
diff_in_one = dircomp.diff_files
# 3 更新临时存储的文件列表 所在的目录
# 3-1 获取绝对路径
dirpath = os.path.abspath(dir1)
# 3-2 获取左侧唯一的内容
[hoderlist.append(os.path.abspath(os.path.join(dir1,x))) for x in only_in_one]
# 3-3 获取左侧不匹配的内容
[hoderlist.append(os.path.abspath(os.path.join(dir1, x))) for x in diff_in_one]
# 4 递归方式获取所有文件信息
if len(dircomp.common_files) > 0:
# 4-1 遍历所有的子目录
for item in dircomp.common_dirs:
# 4-2 对所有的子目录进行内容比对 - 使用方法本身
compareme(os.path.abspath(os.path.join(dir1,item)),os.path.abspath(os.path.join(dir2,item)))
# 5 返回更新后的文件列表
return hoderlist
# 2 主函数方法
def main():
# 1 准备工作
# 1-1 接收两个脚本参数及脚本的使用方式
if len(sys.argv) > 2:
dir1 = sys.argv[1]
dir2 = sys.argv[2]
else:
print("脚本的使用方式:脚本名 目录1 目录2")
sys.exit()
# 1-2 目录的准备工作
source_files = compareme(dir1,dir2) # 获取待同步的目录
dir1 = os.path.abspath(dir1) # 获取待同步的目录位置
destination_files = [] # 要同步的目录路径
createdir_bool = False # 新增目录的时候,设定的标识符
# 2 目录创建
# 2-1 获取待同步的所有目录结构 - 通过替换的方式实现目标目录的确定
# 这是已存在的目录内容同步
for item in source_files:
# 目标目录的列表同步
destination_dir = re.sub(dir1,dir2,item)
destination_files.append(destination_dir)
# 对目标目录进行简单的判断,如果不存在就创建
if os.path.isdir(item):
if not os.path.exists(destination_dir):
os.makedirs(destination_dir)
createdir_bool = True
# 2-2 同步目录 - 必须保证临时目录createdir_bool是True
# 这是刚才新建的目录内容同步
if createdir_bool:
destination_files = []
source_files = []
source_files = compareme(dir1,dir2)
for item in source_files:
destination_dir = re.sub(dir1,dir2,item)
destination_files.append(destination_dir)
# 3 文件的同步
# 3-1 提示同步更新
print("更新item:")
print("需要同步的文件:{}".format(source_files))
# 3-2 便于cp命令的实现,我们将源文件路径和目标文件路径生成数据对
copy_pair = zip(source_files,destination_files)
# 3-3 开始进行数据的复制
for item in copy_pair:
if os.path.isfile(item[0]):
shutil.copyfile(item[0],item[1])
# 样式:cp file1 file2
# 3 执行
if __name__ == '__main__':
main()
结果:
更新item:
需要同步的文件:['/home/user1/dir1/f4']
运行前
运行后:
实践3 - 在一个子目录下生成文件
思考:
如何一步到位,将多层子目录全部同步完毕,然后将所有的文件同步成功
- - 在比对的时候,做while 循环即可
- - 就是目录创建
此步没有代码,自行实现。