我在.Net 4.0中使用DirectoryInfo和FileInfo来枚举目录树中的文件,并且我遇到了PathTooLongException。简化版本在
之下public static class Test
{
public static void Search(DirectoryInfo base)
{
foreach(var file in base.GetFiles())
{
try
{
Console.WriteLine(file.FullName);
} catch(PathTooLongException ex)
{
// What path was this?
}
}
foreach(var dir in base.GetDirectories())
{
Search(dir);
}
}
}
当抛出错误时,我想知道导致问题的文件路径。显然我不能要求FullName
因为这是错误的。我可以从file.Name
获取名称,但如果我无法获得其余路径,file.Directory
会提供PathTooLongException
,即使DirectoryInfo
找到了该文件的file.FullPath
工作得很好! (我不能使用它,因为实际的代码要复杂得多)。
查看堆栈跟踪,似乎它正在使用内部路径(我从调试中看到受保护的System.IO.Path.NormalizePath
),并试图从完整(超大)路径中撕掉目录。大多数问题似乎涉及{{1}},我听说在.Net 4.0中经历了一些变化。我还没有尝试过该框架的早期版本。
我的问题:
提前感谢您的帮助,
安迪
答案 0 :(得分:6)
除了使用反射,或者使用库或P / Invoke来使用支持长路径和手动检查长度的Windows API之外,我无法想到任何其他方法。完整路径存储在名为protected string
FullPath
字段中
foreach(var dir in new DirectoryInfo (@"D:\longpaths")
.GetFileSystemInfos("*.*", SearchOption.AllDirectories))
{
try
{
Console.WriteLine(dir.FullName);
}
catch (PathTooLongException)
{
FieldInfo fld = typeof(FileSystemInfo).GetField(
"FullPath",
BindingFlags.Instance |
BindingFlags.NonPublic);
Console.WriteLine(fld.GetValue(dir)); // outputs your long path
}
}
如果您尝试实际对文件执行某些操作而不仅仅检查文件长度,我建议使用类似from the BCL team at Microsoft的库,但不会创建DirectoryInfos
,FileInfo
或FileSystemInfo
,仅限字符串。所以它似乎不是你的代码的直接替代品。
至于你的第二个问题的答案,我建议阅读this blog post处理.NET中的长路径。这是它的一个引用,它解释了为什么他们没有快速在.NET中添加长路径支持。
很少有人抱怨32K的限制,所以问题解决了吗?不完全的。有几个原因我们过去不愿意添加长路径,以及为什么我们仍然需要注意它,与安全性,Windows API中的\?\语法和应用程序兼容性的不一致支持有关。
这是一个由3部分组成的系列,并解释了为什么API就是这样的原因以及为什么存在限制。