coPaw在Windows上运行报跨磁盘驱动器文件操作问题修复
coPaw在Windows上运行报跨磁盘驱动器文件操作问题修复
问题描述
在 Windows 上,当使用 Python 的 Path.replace() 进行原子文件写入时,如果临时文件和目标文件位于不同的磁盘驱动器,会抛出以下错误:
OSError: [WinError 17] 系统无法将文件移到不同的磁盘驱动器。
典型场景
# 原子写入模式:先写临时文件,再替换原文件
tmp_path = target_path.with_suffix(target_path.suffix + ".tmp")
tmp_path.write_text(content)
tmp_path.replace(target_path) # 跨驱动器时失败
原因分析
- Windows 的
MoveFileExAPI 在跨卷移动时不会进行原地原子替换 Path.replace()在 Windows 上依赖于这个 API,跨驱动器操作会失败- Linux/macOS 没有这个问题(使用
rename()系统调用)
解决方案
使用 try-except 捕获 OSError,跨驱动器场景下回退到复制+删除:
try:
# 尝试原子替换(同驱动器场景)
tmp_path.replace(target_path)
except OSError:
# 跨驱动器场景:复制后删除
import shutil
shutil.copy2(tmp_path, target_path)
tmp_path.unlink()
优点
- 向后兼容:同驱动器场景仍使用高效的原子操作
- 优雅降级:跨驱动器场景自动回退到复制模式
- 简单可靠:不依赖额外库,标准 Python 代码
影响的文件
修复了以下 CoPaw 项目中的文件:
src/copaw/app/runner/repo/json_repo.py- chats.json 读写src/copaw/app/crons/repo/json_repo.py- jobs.json 读写
类似问题
项目中可能存在相同模式的代码,建议全局搜索并统一修复:
grep -r "\.replace(" --include="*.py" src/
参考资料
- Python
pathlib.Path.replace()文档 - Windows
MoveFileExAPI 文档

浙公网安备 33010602011771号