watchdog是跨平台监听文件增删改最可靠的方案,封装Windows ReadDirectoryChangesW、macOS FSEvents、Linux inotify等原生API,避免轮询高开销与延迟;需注意路径规范、递归设置、事件过滤及防抖去重。

用 watchdog 监听文件系统事件最可靠
Windows/macOS/Linux 上监听文件增删改,watchdog 是目前最稳定的选择。它封装了各平台原生 API(如 Windows 的 ReadDirectoryChangesW、macOS 的 FSEvents),避免轮询带来的 CPU 升高和延迟问题。
安装后直接监听目录即可,注意别用 time.sleep() 轮询——不仅漏事件,还可能卡住主线程:
pip install watchdog
常见错误是监听路径末尾带斜杠(如 "./data/"),部分版本会静默失败;应统一用 os.path.abspath("./data") 或字符串结尾不带 /。
- 只监听指定后缀(如
.txt、.pdf)时,在on_created/on_modified回调里加if event.src_path.endswith((".txt", ".pdf")): - 递归监听子目录设
recursive=True,但深层嵌套可能触发系统句柄数限制(Linux 默认 1024),需配合ulimit -n 4096调整 - 临时文件(如
~$report.docx、.DS_Store)建议过滤,否则频繁误触发
上传到云端优先选 boto3(AWS S3)或 google-api-python-client
同步逻辑本身简单:捕获到 CreatedEvent 就上传,ModifiedEvent 就覆盖,DeletedEvent 就删远端对应对象。但关键在「怎么传才稳」:
立即学习“Python免费学习笔记(深入)”;
-
boto3支持分块上传(upload_file自动处理)、断点续传(ExtraArgs={"Metadata": {...}}可存校验值),比手写 HTTP 请求靠谱得多 - Google Drive 需先用
service.files().create()创建文件,再media_body=MediaFileUpload(...)上传,且单次最大 5GB,超限必须走分片接口 - 所有上传操作必须加异常捕获:
ClientError(权限/桶不存在)、ConnectionError(网络抖动)、ReadTimeout(大文件上传慢)——漏掉任一都可能导致本地已删、云端没删的不一致
别把密钥硬编码进脚本。用 ~/.aws/credentials 或 os.environ["GOOGLE_CLOUD_TOKEN"] 注入,本地开发可配 .env 文件 + python-dotenv 加载。
inotify 在 Linux 下更轻量,但跨平台就得换方案
如果只跑在 Linux 服务器上,inotify + inotifywait 命令行工具组合比 Python 全栈更省资源。例如一行命令就能监听并触发上传:
inotifywait -m -e create,modify,delete ./data | while read path action file; do python upload.py "$path$file"; done
但它没法跨平台:Windows 没 inotify,macOS 要装 fswatch,维护两套逻辑成本高。除非明确限定部署环境,否则还是统一用 watchdog 更省心。
另外,inotifywait 默认对每个事件单独触发一次 shell,高频写入(如日志滚动)会导致进程爆炸,得加 -q 和 --format 合并事件,或用 -t 1 批量等待。
同步冲突和重复上传必须靠本地状态缓存解决
文件刚创建就修改(如编辑器先写空文件再填充内容),watchdog 可能发出 CreatedEvent + ModifiedEvent 两个事件,导致同一文件上传两次。解决方案不是忽略 ModifiedEvent,而是维护一个内存字典记录「最近 5 秒内已上传的文件路径 + 最后修改时间戳」:
- 收到事件时,先查该路径是否在缓存中且时间戳未变,是则跳过
- 上传成功后更新缓存时间戳;失败则保留旧时间戳,下次重试
- 缓存用
LRU cache或简单dict即可,无需持久化——断电重启后首次全量比对也只多花几秒
真正难的是双向同步(本地改了云也改了)。纯单向同步(本地 → 云)可规避此问题,但业务要求双向时,必须引入 etag 或 hash 校验,且要处理「云删了本地还有」这类场景——这时候光靠监听不够,得定期 list_objects_v2 对比元数据。


















