【问题标题】:Retrieve path information from PathTooLongException从 PathTooLongException 中检索路径信息
【发布时间】:2012-03-06 17:51:16
【问题描述】:

我在 .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,我听说在.Net 4.0 中经历了一些变化。我没有尝试过以前版本的框架。

我的问题:

  1. 如何从这个异常中获取完整路径;它似乎在没有任何有用信息的情况下通过了。
  2. 为什么框架需要限制路径中的字符来截断文件名?

提前感谢您的帮助,
安迪

【问题讨论】:

    标签: c# .net windows path pathtoolongexception


    【解决方案1】:

    除了使用反射,或者使用库或 P/Invoke 来使用支持长路径和手动检查长度的 Windows API 之外,我想不出任何其他方法。完整路径存储在名为FullPathprotected string 字段中

    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 这样的库,但它不会创建 @987654327 @、FileInfoFileSystemInfo,仅限字符串。因此,它可能不是您的代码的直接替代品。

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

    很少有人抱怨 32K 的限制,那么,问题解决了吗?不完全的。过去我们不愿意添加长路径有几个原因,以及为什么我们仍然对此保持谨慎,与安全性、Windows API 对 \?\ 语法的支持不一致以及应用兼容性有关。

    这是一个由 3 部分组成的系列,解释了 API 为何如此的几个原因以及存在限制的原因。

    【讨论】:

    • 谢谢克里斯托弗,我担心会是这样。私下持有路径并且在不先验证它的情况下不允许访问它似乎很愚蠢......即使它为我创建了无效路径就好了。您指向的LongPath 库看起来很棒!不幸的是,我忘了提到所有路径都将是 UNC,因此(还)不能按原样使用。不过,查看代码以了解如何实现直接 API 将非常有用。
    • @Andyrooger,是的,我忘记了。我分叉了代码并在不久前添加了它。您可以获取代码at its codeplex project。使用源代码,而不是发布,我修复了一个愚蠢的错误。
    • @ChristopherCurrens +1 获取 FieldInfo 提示!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-10
    • 2017-08-15
    相关资源
    最近更新 更多