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

Python脚本能否完整复制含子文件夹的目录并实现复制监控?

问题解答

1. 原脚本是否能复制包含子文件夹的完整目录?

原脚本的shutil.copytree本身支持递归复制所有子文件夹及文件,但存在两个冗余/问题点:

  • 代码中files = os.listdir(src_dir)这一行完全无用,copytree会自行遍历源目录的所有层级内容
  • 若目标目录dest_dir已存在,copytree会直接抛出FileExistsError导致复制中断(Python 3.8+可通过dirs_exist_ok=True参数解决)

2. 如何实现复制文件的实时监控?

原脚本的日志函数仅打印当前处理的目录,无法监控单个文件的复制状态。可以通过以下两种方式实现文件级监控:

方式一:自定义复制函数配合shutil.copytree

修改脚本,添加自定义复制函数记录每个文件的复制操作,同时完善日志配置:

import shutil
import os
import logging

# 配置日志:输出到控制台,显示时间、级别和内容
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s',
    handlers=[logging.StreamHandler()]
)

def copy_with_log(src_file, dest_file):
    """带日志的文件复制函数,保留文件元数据"""
    logging.info(f"正在复制: {src_file} -> {dest_file}")
    try:
        shutil.copy2(src_file, dest_file)
    except Exception as e:
        logging.error(f"复制失败 [{src_file}]: {str(e)}")

def log_current_dir(path, names):
    """记录当前处理的目录"""
    logging.info(f"处理目录: {path}")
    return []  # 不忽略任何文件或子目录

src_dir = r'\\networkDrive1\allFolders'
dest_dir = r'\\networkDrive2\folder1\folder2\destinationFolder'

# 处理目标目录已存在的情况(Python 3.8+支持dirs_exist_ok)
if os.path.exists(dest_dir):
    logging.warning(f"目标目录 {dest_dir} 已存在,将跳过已存在的目录结构")

shutil.copytree(
    src_dir,
    dest_dir,
    ignore=log_current_dir,
    copy_function=copy_with_log,
    dirs_exist_ok=True  # 允许目标目录存在,避免报错
)

方式二:用os.walk手动遍历复制(更灵活)

通过os.walk遍历源目录的所有层级,逐个复制文件,适合需要更精细控制的场景:

import shutil
import os
import logging

logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s',
    handlers=[logging.StreamHandler()]
)

src_dir = r'\\networkDrive1\allFolders'
dest_dir = r'\\networkDrive2\folder1\folder2\destinationFolder'

for root, dirs, files in os.walk(src_dir):
    # 构建当前目录在目标路径中的对应位置
    target_root = root.replace(src_dir, dest_dir, 1)
    # 创建目标目录(不存在则创建,已存在则跳过)
    os.makedirs(target_root, exist_ok=True)
    logging.info(f"进入目录: {root}")
    
    for file in files:
        src_path = os.path.join(root, file)
        target_path = os.path.join(target_root, file)
        
        # 可选:跳过已存在的文件
        if os.path.exists(target_path):
            logging.debug(f"文件已存在,跳过: {target_path}")
            continue
        
        logging.info(f"正在复制: {src_path} -> {target_path}")
        try:
            shutil.copy2(src_path, target_path)
        except Exception as e:
            logging.error(f"复制失败 [{src_path}]: {str(e)}")

额外注意事项

  • 针对1TB的大体积网络复制,建议添加重试机制(比如复制失败时重试2-3次),避免因网络波动中断任务
  • shutil.copy2会保留文件的元数据(修改时间、权限等),若无需保留可改用shutil.copy
  • 若需要持久化日志,可在logging.basicConfig中添加logging.FileHandler('copy_task.log'),将日志同时写入文件

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 20:43:17