从PathTooLongException中检索路径信息

时间:2012-03-06 17:51:16

标签: c# .net windows path pathtoolongexception

我在.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中经历了一些变化。我还没有尝试过该框架的早期版本。

我的问题:

  1. 如何从此异常中获取完整路径;它似乎没有任何有用的信息。
  2. 为什么框架需要限制路径中的字符来切断文件名?
  3. 提前感谢您的帮助,
    安迪

1 个答案:

答案 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的库,但不会创建DirectoryInfosFileInfoFileSystemInfo,仅限字符串。所以它似乎不是你的代码的直接替代品。

至于你的第二个问题的答案,我建议阅读this blog post处理.NET中的长路径。这是它的一个引用,它解释了为什么他们没有快速在.NET中添加长路径支持。

  

很少有人抱怨32K的限制,所以问题解决了吗?不完全的。有几个原因我们过去不愿意添加长路径,以及为什么我们仍然需要注意它,与安全性,Windows API中的\?\语法和应用程序兼容性的不一致支持有关。

这是一个由3部分组成的系列,并解释了为什么API就是这样的原因以及为什么存在限制。