File.Copy 默认覆盖目标文件,需显式传 true;目标目录不存在会抛异常,须提前创建;跨卷复制为全量读写,同卷建议用 File.Move;大文件应后台线程执行并手动流式复制。

File.Copy 会覆盖目标文件吗?
默认会,File.Copy 第三个参数 overwrite 不传或传 false 时,目标存在就直接抛异常:System.IO.IOException: The file 'xxx' already exists.。必须显式传 true 才能覆盖。
实操建议:
- 如果业务逻辑允许覆盖(如更新配置、同步缓存),直接用
File.Copy(source, dest, true) - 如果要避免误覆盖,先用
File.Exists(dest)判断,再决定是跳过、重命名还是报错提示 - 注意:即使
overwrite = true,目标文件若被其他进程占用(如 Excel 正在打开),仍会抛UnauthorizedAccessException
复制大文件时卡住或内存爆掉怎么办?
File.Copy 是同步阻塞调用,内部使用缓冲区逐块读写,一般不会吃光内存;但若源文件极大(>1GB)且磁盘 I/O 慢,会明显卡主线程。它不提供进度回调,也没法取消。
实操建议:
- UI 场景(如 WinForms/WPF)务必丢到后台线程,避免界面冻结:
Task.Run(() => File.Copy(...)) - 需要进度反馈或可取消,得手写流式复制,用
FileStream+BufferedStream控制每次读取大小(如 8192 字节) - 别用
File.ReadAllBytes() + File.WriteAllBytes()—— 这会把整个文件加载进内存,几 GB 文件直接 OOM
目标目录不存在时会自动创建吗?
不会。File.Copy 只操作文件,不管目录。如果 dest 路径中的父目录(如 C:\backup\project\)不存在,会抛 DirectoryNotFoundException。
实操建议:
- 复制前主动创建目录:
Directory.CreateDirectory(Path.GetDirectoryName(dest))—— 注意这个方法是幂等的,目录存在也不报错 - 别用
Directory.CreateSubdirectory,它要求父目录必须已存在,不如CreateDirectory直接 - 路径拼接别手拼字符串,用
Path.Combine(srcDir, "file.txt")避免反斜杠/正斜杠混乱
跨卷复制(比如 C 盘到 D 盘)和同卷移动性能差别大吗?
有本质区别。同卷复制实际是「创建新硬链接 + 复制元数据」,极快;跨卷才是真拷贝,走完整读写流程。但 File.Copy 对两者无感知,都走同一套逻辑。
实操建议:
- 如果确定是同卷且想“假装”移动(比如归档后删原文件),优先用
File.Move,它底层调用系统 MoveFile API,同卷近乎瞬时 - 不要指望
File.Copy自动优化跨卷场景——它没法判断是否同卷,也不会降级为硬链接 - 真正影响体验的是磁盘类型(机械盘 vs NVMe)和文件碎片程度,这些跟代码无关,得靠运维层面优化
路径权限、长文件名(>260 字符)、符号链接处理这些点容易漏,尤其在 Windows Server 或容器环境下跑 C# 程序时,得提前检查 App.manifest 是否启用了 longPathAware 和对应文件系统权限。










