应先用directory.getfiles精准匹配再逐个删除,避免directory.delete误删或报错;需处理权限、占用、只读等异常,并注意中文路径、acl跳过、句柄未释放等问题。

用 Directory.GetFiles 精准匹配再删,别直接 Directory.Delete
批量删指定格式文件,核心是「先找对,再动手」。很多人图省事用 Directory.Delete(path, true) 整目录清空,结果误删非目标文件,或因权限/占用报错中断。真正安全的做法是先枚举、过滤、再逐个删除。
常见错误现象:UnauthorizedAccessException(权限不足)、IOException(文件正被占用)、删了不该删的配置文件或子目录。
-
Directory.GetFiles支持通配符,比如"*.log"、"temp_*.tmp",但不递归——要遍历子目录得加SearchOption.AllDirectories - 如果路径含中文或特殊字符,确保传入的是完整、已转义的
string,不要拼接未清理的用户输入 - 删除前建议用
File.GetAttributes检查是否为只读,否则File.Delete会静默失败(.NET 6+ 会抛异常,旧版本可能跳过)
递归删 .tmp 文件时,为什么 SearchOption.AllDirectories 有时漏掉某些子目录?
不是 API 有 bug,而是权限或访问控制列表(ACL)导致跳过。.NET 在遍历时遇到无权访问的子目录,默认静默跳过,不抛异常也不计入结果。
使用场景:清理临时文件夹(如 %TEMP%),里面常混着系统或其它进程创建的受限子目录。
- 必须手动捕获
UnauthorizedAccessException和DirectoryNotFoundException,并在 try/catch 中继续遍历兄弟目录 - 避免用
Directory.EnumerateFiles直接链式调用再删——它底层仍走同样路径,异常处理逻辑没变 - 若需强一致性,可先用
Directory.GetDirectories获取所有子路径,再逐个try/catch调用GetFiles
File.Delete 报 IOException: The process cannot access the file 怎么办?
文件正被另一个线程、进程或 .NET 自身的 FileStream 持有句柄,这是最常见原因。不是代码写错了,而是资源没释放干净。
性能影响:反复重试删除会拖慢清理速度;盲目加 Thread.Sleep 又不可靠。
- 检查代码里是否有未
Dispose()的FileStream、Image.FromFile、XmlReader.Create等——它们默认保持文件句柄打开 - 删之前用
try { File.Move(path, path); }快速探测是否可访问(比File.Exists更准) - 生产环境慎用「重试 3 次 + 延迟」策略;更稳妥的是记录失败路径,交由后续人工或异步任务处理
清空目录但保留结构,为什么不用 Directory.Delete + Directory.CreateDirectory?
因为重建目录会丢失原始 ACL、创建时间、隐藏/系统属性,甚至触发防病毒软件警报。尤其在服务账户运行时,新建目录权限常比原目录宽松,埋下安全隐患。
兼容性影响:Windows Server 上 NTFS 权限继承行为复杂,CreateDirectory 不自动恢复父目录的继承设置。
- 正确做法是遍历
Directory.GetFiles+Directory.GetDirectories,分别删文件、清空子目录(递归调用自身),最后不删根目录 - 若需保留空子目录,注意
GetDirectories返回的是路径数组,删完其下内容后无需额外操作 - 对超大目录(>10k 文件),考虑用
Directory.EnumerateFiles避免一次性加载全量路径到内存
最易被忽略的点:没有检查文件是否正在被写入。即使删之前 File.Exists 返回 true,下一毫秒它就可能被另一个进程 FileStream 打开——所以异常处理不是备选方案,是必选项。











