directory.delete(path, true) 会失败,因为 windows api 的 deletefile 拒绝删除带 file_attribute_readonly 标志的文件,即使递归参数为 true 也不会自动清除只读属性;必须先遍历所有文件和子目录(从内到外),用位运算清除只读位(保留其他属性),再执行删除。
为什么 Directory.Delete(path, true) 会失败
因为 .NET 的 Directory.Delete 默认调用 Windows API 的 DeleteFile,而该 API 拒绝删除带有 FILE_ATTRIBUTE_READONLY 标志的文件。即使你传了 true(递归),它也不会自动清除只读属性——它只是逐个尝试删,遇到只读文件就抛 UnauthorizedAccessException 或 IOException。
必须先遍历并清除只读属性
核心思路:不能依赖“强制删除”参数,得手动把所有文件和子目录的只读位去掉。注意两点:一是属性修改要从里往外(先子项后父项),二是目录本身也可能被设为只读(比如 Git 创建的空目录)。
实操建议:
- 用
Directory.GetFiles(path, "*", SearchOption.AllDirectories)获取全部文件路径,逐个调用File.SetAttributes(file, File.GetAttributes(file) & ~FileAttributes.ReadOnly) - 再用
Directory.GetDirectories(path, "*", SearchOption.AllDirectories)获取所有子目录(按深度降序排列),对每个目录执行同样操作:Directory.SetAttributes(dir, Directory.GetAttributes(dir) & ~FileAttributes.ReadOnly) - 最后才调用
Directory.Delete(path, true)
更安全的写法:用 FileAttributes 位运算而非直接赋值
别用 File.SetAttributes(file, FileAttributes.Normal) ——这会清掉隐藏、系统等其他属性,可能破坏程序或系统行为。正确做法是只清除只读位,保留其余属性不变: