C#中使用多通配符跳过无限递归的Application Data目录
解决C:\Users目录遍历中Application Data无限递归的问题
问题背景
我在递归遍历c:\Users目录时遇到了一个烦人的问题:c:\Users\username\AppData\Local\Application Data\Application Data\Application Data……会无限递归下去。后来了解到,这个Application Data是Windows系统为了兼容旧程序设置的快捷目录(Junction Point),它实际指向的就是上级的Local目录,所以才会出现这种无限套娃的情况。
我想跳过这个子目录继续遍历,请问用下面的代码能不能实现?
foreach (string file in Directory.GetFiles(path) { do stuff } foreach (string subdir in Directory.GetDirectories(path) { if (subdir == "c:\\Users\\*\\AppData\\Local\\Application Data\\*") { continue; } recusivecall(subdir); }
分析与解决方案
你的思路是对的——跳过这个特殊目录就能解决无限递归,但代码里的判断方式有问题:C#里直接用==匹配带通配符*的路径是不生效的,subdir是完整的具体路径,没法和通配符字符串直接相等匹配。
给你两种更可靠的实现方式:
方法1:基于路径和目录名判断
直接检查子目录是否是AppData\Local下的Application Data目录,简单直接:
void RecursiveTraverse(string path) { // 处理当前目录下的文件 foreach (string file in Directory.GetFiles(path)) { // 替换成你的文件处理逻辑 Console.WriteLine($"Processing file: {file}"); } foreach (string subdir in Directory.GetDirectories(path)) { // 获取当前子目录的名称和父目录路径 string dirName = Path.GetFileName(subdir); string parentDir = Path.GetDirectoryName(subdir); // 判断是否是目标问题目录:名称是Application Data,且父目录是AppData\Local bool isProblemDir = string.Equals(dirName, "Application Data", StringComparison.OrdinalIgnoreCase) && parentDir.EndsWith(@"AppData\Local", StringComparison.OrdinalIgnoreCase); if (isProblemDir) { Console.WriteLine($"Skipping problematic directory: {subdir}"); continue; } // 递归遍历其他子目录 RecursiveTraverse(subdir); } }
方法2:判断是否是系统快捷目录(更严谨)
因为可能存在同名的普通目录,所以可以结合目录的重解析点属性来判断它是不是系统的Junction Point:
void RecursiveTraverse(string path) { foreach (string file in Directory.GetFiles(path)) { // 你的文件处理逻辑 Console.WriteLine($"Processing file: {file}"); } foreach (string subdir in Directory.GetDirectories(path)) { DirectoryInfo dirInfo = new DirectoryInfo(subdir); // 判断是否是Junction Point(重解析点+目录属性),且名称是Application Data bool isJunctionAppData = (dirInfo.Attributes & FileAttributes.ReparsePoint) != 0 && (dirInfo.Attributes & FileAttributes.Directory) != 0 && string.Equals(dirInfo.Name, "Application Data", StringComparison.OrdinalIgnoreCase); if (isJunctionAppData) { Console.WriteLine($"Skipping junction directory: {subdir}"); continue; } RecursiveTraverse(subdir); } }
关键说明
- 用
StringComparison.OrdinalIgnoreCase是为了兼容Windows系统的大小写不敏感特性,避免因为路径大小写差异导致判断失败。 - 方法2更严谨,能准确区分系统的快捷目录和普通同名目录,推荐使用。
内容的提问来源于stack exchange,提问作者IUAfroMan97
相关产品推荐
相关产品推荐

