You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Windows使用shutil.move跨磁盘移动文件报错WinError 17怎么解决?

问题解决方案

报错原因

WinError 17 跨磁盘移动失败的核心触发点有3个:

  • 你当前使用的on_modified事件会在目录发生任何改动时反复触发,移动文件的操作本身会修改原监听目录,导致回调重复执行,出现文件被占用、重复移动的冲突
  • 硬编码拼接路径的方式在Windows环境下容易出现路径格式不兼容,shutil.move无法正确识别跨盘路径
  • 未判断文件状态就直接执行移动,可能触发未完全下载/被其他程序占用的文件的移动操作

修复步骤

  1. 补全缺失的依赖导入,你的原代码未导入os、Observer、FileSystemEventHandler相关模块
  2. 使用os.path.join拼接路径,适配Windows系统的路径规则
  3. 增加文件状态判断、重复触发拦截逻辑,避免重复执行移动操作
  4. 增加目标路径存在校验,避免同名文件冲突

修复后完整代码

import os
import shutil
import time
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler

# 增加全局锁避免重复触发回调
is_moving = False
folder_to_track = '/Users/sia/Downloads/Telegram Desktop'
folder_destination = 'D:/test_folder'

# 先确保目标文件夹存在
os.makedirs(folder_destination, exist_ok=True)

class MyHandler(FileSystemEventHandler):
    def on_modified(self, event):
        global is_moving
        if is_moving:
            return
        is_moving = True
        try:
            # 等待1秒避免文件还在写入中就被移动
            time.sleep(1)
            for filename in os.listdir(folder_to_track):
                src = os.path.join(folder_to_track, filename)
                # 跳过文件夹,只处理文件
                if not os.path.isfile(src):
                    continue
                new_destination = os.path.join(folder_destination, filename)
                # 处理同名文件,自动加后缀
                counter = 1
                while os.path.exists(new_destination):
                    name, ext = os.path.splitext(filename)
                    new_destination = os.path.join(folder_destination, f"{name}_{counter}{ext}")
                    counter += 1
                shutil.move(src, new_destination)
        finally:
            is_moving = False

event_handler = MyHandler()
observer = Observer()
observer.schedule(event_handler, folder_to_track, recursive=True)
observer.start()

# 保持程序运行
try:
    while True:
        time.sleep(1)
except KeyboardInterrupt:
    observer.stop()
observer.join()

额外注意事项

  • 如果你要移动的文件正被Telegram等程序占用,需要等文件完全下载、程序释放文件占用后再执行移动操作
  • 如果不需要监听实时移动,只需要一次性迁移所有文件,可以去掉watchdog相关的监听逻辑,直接执行遍历移动的代码即可

内容的提问来源于stack exchange,提问作者siavash

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 19:57:02