.NET 6中FileInfo.CopyTo()覆盖已存在文件时抛出访问拒绝异常
问题产生原因
目标路径下已存在的同名文件带有只读属性,这是FileInfo.CopyTo(..., overwrite: true)方法非常容易被忽略的异常触发场景,目前微软官方文档对该方法抛出UnauthorizedAccessException的条件描述存在遗漏,没有提到这个场景。
你观察到的现象完全符合这个触发逻辑:
- 目标文件不存在时,方法仅需要在目标目录下创建新文件并写入流,只要你拥有目标目录的写入权限就可以正常执行,和文件属性无关。
- 目标文件存在且标记为只读后,
CopyTo的覆盖逻辑不会自动清除目标文件的只读标记,直接尝试向只读文件写入内容就会抛出访问拒绝异常。这种情况下即便你是文件所有者、拥有目录的完全控制权限、目标文件没有被其他进程占用,甚至用管理员身份运行,异常都会正常触发。
你提到可以通过资源管理器或命令行正常删除目标文件,这和只读属性的规则不冲突:Windows系统下删除只读文件不需要额外移除只读属性,但写入、修改只读文件内容的操作会被系统拦截。你可以手动给测试文件勾选只读属性后再运行原代码,会稳定复现这个异常。
修复方案
在执行复制操作前,先检查目标路径是否存在同名文件,如果存在且带有只读属性,先移除只读标记再执行复制即可:
DirectoryInfo targetDir = GetTargetDir(); foreach (FileInfo fi in GetFilesToCopy()) { string targetFilePath = Path.Combine(targetDir.FullName, fi.Name); // 提前处理目标文件的只读属性 if (File.Exists(targetFilePath)) { FileInfo existingTargetFile = new FileInfo(targetFilePath); if (existingTargetFile.IsReadOnly) { existingTargetFile.IsReadOnly = false; } } fi.CopyTo(targetFilePath, true); }
内容的提问来源于stack exchange,提问作者Master_T
相关产品推荐
相关产品推荐

