检索PathTooLongException路径信息路径、信息、PathTooLongException

2023-09-03 22:15:30 作者:爱情,我戒了

我使用的DirectoryInfo和FileInfo的在.NET 4.0中列举的一个目录树中的文件和我打PathTooLongException。简体版本低于

I am using DirectoryInfo and FileInfo in .Net 4.0 to enumerate files in a directory tree and I am hitting PathTooLongException. Simplified version is below

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);
        }
    }
}

在被抛出的错误,我想知道是什么文件路径导致的问题。很显然,我不能要求全名,因为这是什么差错。我可以从 file.Name 得到的名字,但如果我不能得到的路径 file.Directory 给出了一个 PathTooLongException 尽管的DirectoryInfo 被发现从正常工作的文件! (我不能用,虽然作为实际code要复杂得多)。

When the error is thrown, I want to know what file path caused the problem. Obviously I can't ask for FullName as that is what errored. I can get name from file.Name, but if I can't get the rest of the path as file.Directory gives a PathTooLongException even though the DirectoryInfo that the file was found from worked fine! (I can't use that though as the actual code is much more complex).

翻翻堆栈跟踪,似乎它使用一个内部路径(我看到一个受保护的 file.FullPath 从调试),并试图从全撕目录(超大型)路径。大多数的问题似乎涉及 System.IO.Path.NormalizePath ,用我听经历了在.NET 4.0中有一些变化。我没有尝试过的框架previous版本。

Looking through the stack trace it seems that it's using an internal path (I see a protected file.FullPath from debug), and trying to tear the directory from the full (oversized) path. Most of the problems seem to involve System.IO.Path.NormalizePath, with I hear went through a few changes in .Net 4.0. I have not tried on previous versions of the framework.

我的问题:

我怎样才能从这种异常的完整路径;它似乎没有进行任何有用的信息。 为什么会框架需要限制字符的路径砍掉的文件名?

在此先感谢您的帮助, 刘德华

Thanks in advance for any help, Andy

推荐答案

我想不出任何其他方式把我的头比使用反射,或使用图书馆或P / Invoke来使用Windows API的其他顶部支持长路径和手动检查长度。完整路径存储在一个保护字符串字段名为 FULLPATH

I can't think of any other way off the top of my head other than using reflection, or using a library or P/Invoke to use the Windows APIs that support long paths and manually check length. The full path is stored in a protected string field called 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首创置业团队在微软,但它不会创建 DirectoryInfos 的FileInfo FileSystemInfo ,只有字符串。因此,这可能不是一个简易替换为您的code似乎。

If you're trying to actually do something with the files and not just check file length, I would suggest using a library like this one from the BCL team at Microsoft, however it doesn't create DirectoryInfos, FileInfo or FileSystemInfo, only strings. So it's might not be a drop-in replacement for your code it seems.

至于回答你的第二个问题,我建议你阅读this博客文章的处理在.NET长路径。这是它报价,解释为什么他们还没有快速补充长路径的支持.NET。

As for the answer to your second question, I recommend reading this blog post dealing with long paths in .NET. This is a quote from it that explains why they haven't been quick to add long path support in .NET.

很少有人抱怨32K的限制,所以,问题就解决了​​?不太。有几个原因,我们都不愿意过去增加长路径,为什么我们还是小心一下,涉及到安全,不一致支持的\?\语法Windows的API和应用程序的兼容性。

Very few people complain about a 32K limit, so, problem solved? Not quite. There are several reasons we were reluctant to add long paths in the past, and why we’re still careful about it, related to security, inconsistent support in the Windows APIs of the \?\ syntax, and app compatibility.

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

It's a 3 part series and explains a few reasons why the API is the way it is and why the limitation is there.