当前位置: 首页 > news >正文

【Python】实现一个文件夹快照与比较工具

1. 工具简介

在日常开发、项目管理或备份场景中,我们经常需要知道某个文件夹中的文件是否发生变化,例如:

  • 项目源码是否新增或修改文件?
  • 数据集是否被不小心删除或篡改?
  • 备份文件夹是否和上次一致?

本教程将教你如何编写一个简单的 Python 命令行工具,只基于文件内容哈希值(SHA256) 来检测变化。


2. 功能设计

该工具支持两个核心命令:

命令作用
create创建当前文件夹的快照,保存为 JSON
compare比较当前文件夹与指定快照文件的差异

命令行格式:

python snapshot.py <目录路径> <create|compare> <快照文件.json>

示例:

# 创建快照
python snapshot.py ./project create snapshot.json# 比较快照
python snapshot.py ./project compare snapshot.json

3. 核心实现思路

  1. 遍历文件夹

    • 递归遍历指定文件夹中的所有文件,并计算每个文件的 SHA256 哈希值。
  2. 快照格式

    • 将快照保存为 JSON 文件,文件路径使用 POSIX 风格的 / 分隔符,保证跨平台一致性。

    • 快照文件结构示例:

      {"main.py": "a3f2f9c91b72e9f8d4f2...","data/input.csv": "e49adf91c7dbe23ff03d..."
      }
      
  3. 比较逻辑

    • 根据快照与当前文件夹的哈希值,分为三类:
      • 新增文件:当前存在但快照中没有的文件
      • 删除文件:快照中存在但当前不存在的文件
      • 修改文件:快照和当前都存在,但哈希值不同

4. 完整代码

下面是实现该工具的完整 Python 代码,只有一个文件,简单易用。

#!/usr/bin/env python3
import os
import sys
import json
import hashlib
from pathlib import Pathdef calc_file_hash(file_path, chunk_size=8192):"""计算文件的 SHA256 哈希值"""sha256 = hashlib.sha256()try:with open(file_path, "rb") as f:while chunk := f.read(chunk_size):sha256.update(chunk)except Exception as e:print(f"[ERROR] Cannot read file: {file_path}, {e}", file=sys.stderr)return Nonereturn sha256.hexdigest()def create_snapshot(directory: Path, output_file: Path):"""创建快照文件,路径统一为 POSIX 风格"""directory = directory.resolve()snapshot = {}for root, _, files in os.walk(directory):for filename in files:abs_path = Path(root) / filename# 统一使用 "/" 作为分隔符rel_path = abs_path.relative_to(directory).as_posix()file_hash = calc_file_hash(abs_path)if file_hash:snapshot[rel_path] = file_hashwith open(output_file, "w", encoding="utf-8") as f:json.dump(snapshot, f, indent=2, ensure_ascii=False)print(f"[OK] Snapshot created: {output_file}")def compare_snapshot(directory: Path, snapshot_file: Path):"""比较当前目录与快照的差异"""with open(snapshot_file, "r", encoding="utf-8") as f:old_files = json.load(f)base_dir = directory.resolve()current_files = {}for root, _, files in os.walk(base_dir):for filename in files:abs_path = Path(root) / filenamerel_path = abs_path.relative_to(base_dir).as_posix()file_hash = calc_file_hash(abs_path)if file_hash:current_files[rel_path] = file_hash# 计算差异added = [f for f in current_files if f not in old_files]deleted = [f for f in old_files if f not in current_files]modified = [f for f in current_files if f in old_files and current_files[f] != old_files[f]]# 输出结果print("\nAdded files:")for f in added:print(f"  + {f}")print("\nDeleted files:")for f in deleted:print(f"  - {f}")print("\nModified files:")for f in modified:print(f"  * {f}")def main():# 参数格式:python snapshot.py <directory> <create|compare> <snapshot.json>if len(sys.argv) != 4:print("Usage: python snapshot.py <directory> <create|compare> <snapshot.json>")sys.exit(1)directory = Path(sys.argv[1])command = sys.argv[2].lower()snapshot_file = Path(sys.argv[3])if command == "create":create_snapshot(directory, snapshot_file)elif command == "compare":compare_snapshot(directory, snapshot_file)else:print("Error: command must be 'create' or 'compare'")sys.exit(1)if __name__ == "__main__":main()

5. 使用示例

假设有如下目录结构:

myfolder/
├─ file1.txt
├─ file2.txt
└─ subdir/└─ image.png

创建快照

python snapshot.py ./myfolder create snapshot.json

生成的 snapshot.json 内容示例:

{"file1.txt": "a3f2f9c91b72e9f8d4f2c5d9c0c3b...","file2.txt": "b74b9ff174c5e00e3e8f93b4c9f0a...","subdir/image.png": "e49adf91c7dbe23ff03dbf7839273..."
}

修改文件并比较

例如:

  • 修改 file2.txt
  • 新增 notes.txt
  • 删除 subdir/image.png

执行比较命令:

python snapshot.py ./myfolder compare snapshot.json

输出结果:

Added files:+ notes.txtDeleted files:- subdir/image.pngModified files:* file2.txt

6. 总结

通过本教程,我们实现了一个简洁高效的命令行工具,实现了以下功能:

  • 记录文件夹的完整快照(基于文件内容哈希)。
  • 快速比较当前文件夹与快照的差异。
  • 跨平台兼容,结果统一、可读。

该工具非常适合日常开发和运维场景,帮助你高效地管理和追踪文件变化。


文章转载自:

http://maf3fhBG.cwyfs.cn
http://tF6hM0nq.cwyfs.cn
http://sJeiDtIB.cwyfs.cn
http://pWkBAPbv.cwyfs.cn
http://vfzJ2WLA.cwyfs.cn
http://dUu1NFnd.cwyfs.cn
http://50BLdyPS.cwyfs.cn
http://yUjv2Bfp.cwyfs.cn
http://9NcbyzJp.cwyfs.cn
http://PzaaeK84.cwyfs.cn
http://WLF7kBH9.cwyfs.cn
http://Ew3vfxYz.cwyfs.cn
http://uZQ0dTDN.cwyfs.cn
http://sBBlM5ti.cwyfs.cn
http://nrp5lxzu.cwyfs.cn
http://8oudBqwy.cwyfs.cn
http://6I6x2n14.cwyfs.cn
http://5DEQ5AG6.cwyfs.cn
http://XCIZ1hxV.cwyfs.cn
http://rFRh5CG5.cwyfs.cn
http://GJIzglGY.cwyfs.cn
http://3NLpVmwV.cwyfs.cn
http://qsnoHHfF.cwyfs.cn
http://2NHLwdNd.cwyfs.cn
http://xnZBsdhw.cwyfs.cn
http://9r9aovDM.cwyfs.cn
http://JyY6lL7Y.cwyfs.cn
http://C7UgQSzB.cwyfs.cn
http://Q8SgMyUx.cwyfs.cn
http://AfRQ0Uc1.cwyfs.cn
http://www.dtcms.com/a/383115.html

相关文章:

  • Python的深度学习
  • 自动化测试的概念
  • [QT]信号与槽
  • 高精度运算:大数计算全攻略
  • LeetCode 3302.字典序最小的合法序列
  • 深入解析3x3矩阵:列优先与行优先约定的全面指南
  • Codeforces 1049 Div2(ABCD)
  • 【开题答辩全过程】以 “居逸”民宿预订微信小程序为例,包含答辩的问题和答案
  • AWS IAM 模块全面优化:实现完整生命周期管理与性能提升
  • RK3568 PWM驱动基础知识
  • 贪心算法应用:钢铁连铸优化问题详解
  • 9. LangChain4j + 整合 Spring Boot
  • 返利app的消息队列架构:基于RabbitMQ的异步通信与解耦实践
  • React Native架构革命:从Bridge到JSI性能飞跃
  • Qt---描述网络请求QNetworkRequest
  • XLua教程之Lua调用C#
  • 第七章:AI进阶之------条件语句(if-elif-else)(一)
  • 从希格斯玻色子到QPU:C++在高能物理与量子计算领域的跨界征程与深度融合
  • 二、vue3后台项目系列——安装相关依赖、项目常用辅助开发工具
  • Knockout.js 备忘录模块详解
  • VS2022下载+海康SDK环境配置实现实时预览
  • 前端基础 —— C / JavaScript基础语法
  • 手搓一个 DELL EMC Unity存储系统健康检查清单
  • 字节M3-Agent:如何实现一个支持多模态长期记忆与推理的Agent
  • TCL华星计划投建第8.6代印刷OLED产线
  • Qt学习:moc生成的元对象信息
  • Java—JDBC 和数据库连接池
  • 软件工程实践四:MyBatis-Plus 教程(连接、分页、查询)
  • 用 Go 快速上手 Protocol Buffers
  • Java Stream 流学习笔记