Getting path information from PathTooLongException

I am using DirectoryInfo and FileInfo in .Net 4.0 to list files in a directory tree and I am hitting PathTooLongException. Simplified version 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);
        }
    }
}

      

When the error occurs, I want to know which file path caused the problem. Obviously I cannot ask FullName

as this is a bug. I can get the name from file.Name

, but if I can't get the rest of the path as it file.Directory

gives PathTooLongException

, even if DirectoryInfo

that file was found from working fine! (I can't use this though, since the real code is much more complicated).

Looking at the stack trace, it seems that it is using an internal path (I can see protected file.FullPath

from debug) and is trying to rip the directory off the full (oversized) path. Most of the problems seem to be related to System.IO.Path.NormalizePath

, and I heard that some changes happened in .Net 4.0. I have not tried previous versions of the framework.

My questions:

  • How can I get the full path from this exception; it appears to have been transmitted without any useful information.
  • Why does a frame need to limit characters in the path to shred the filename?

Thanks in advance for your help,
Andy

+3


source to share


1 answer


I can't think of anything other than using reflection, or using a library or P / Invoke to use Windows APIs that support long paths and manually check the length. The full path is stored in a field protected string

calledFullPath

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

      

If you are trying to actually do something with the files and not just check the 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. Therefore, it might not be a replacement for your code.



Regarding the answer to your second question, I recommend reading this blog post on long paths in .NET. This is a quote from this that explains why they were unable to add long path support to .NET.

Very few people complain about the 32K limit, so the problem is solved? Not really. There are several reasons why we did not want to add long paths in the past, and why they were still cautious related to security, inconsistent support in the Windows API for syntax \\\ syntax and application compatibility.

This is a three-part series and explains several reasons why the API is and why there is a limitation.

+6


source







All Articles