c # - Hent vejinformation fra PathTooLongException

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg bruger DirectoryInfo og FileInfo i .Net 4.0 til at optage filer i et katalogtræ og jeg rammer PathTooLongException. Forenklet version er nedenfor


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


Når fejlen er kastet, vil jeg gerne vide, hvilken filsti der forårsagede problemet. Selvfølgelig kan jeg ikke bede om FullName da det er det, der fejlede. Jeg kan få navn fra file.Name, men hvis jeg ikke kan få resten af ​​stien som file.Directory, giver en [[PathTooLongException selvom DirectoryInfo at filen blev fundet fra fungerede fint! (Jeg kan ikke bruge det selvom den faktiske kode er meget mere kompleks).


Når man ser gennem stakkesporet, ser det ud til, at det bruger en intern sti (jeg ser en beskyttet file.FullPath fra debug) og forsøger at rive biblioteket fra den fulde (overdimensionerede) sti. De fleste af problemerne synes at involvere System.IO.Path.NormalizePath, med jeg hørte gik gennem et par ændringer i. Net 4.0. Jeg har ikke prøvet på tidligere versioner af rammen.


Mine spørgsmål:



  1. Hvordan kan jeg få den fulde sti fra denne undtagelse; det er tilsyneladende bestået uden nogen nyttige oplysninger.

  2. Hvorfor skal rammerne begrænse tegn i en sti for at hente filnavnet?



Tak på forhånd for enhver hjælp,

Andy

Bedste reference


Jeg kan ikke tænke på nogen anden måde fra toppen af ​​mit hoved end at bruge refleksion eller bruge et bibliotek eller P/Invoke til at bruge Windows API'erne, der understøtter lange stier og manuelt check længden. Den fulde sti er gemt i en [[protected string felt kaldet 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
    }
}


Hvis du forsøger at faktisk gøre noget med filerne og ikke bare kontrollere fillængde, vil jeg foreslå at bruge et bibliotek som dette fra BCL-teamet hos Microsoft, men det skaber ikke DirectoryInfos, FileInfo eller FileSystemInfo, kun strenge. Så det er måske ikke en erstatning for din kode, det forekommer. [15]


Hvad angår svaret på dit andet spørgsmål, anbefaler jeg at læse dette blogindlæg, der omhandler lange stier i .NET. Dette er et citat fra det, der forklarer hvorfor de ikke har været hurtige til at tilføje lang sti support i .NET. [16]



  Meget få mennesker klager over en 32K grænse, så problemet løses? Ikke helt. Der er flere grunde til, at vi var tilbageholdende med at tilføje lange stier i fortiden, og hvorfor vi stadig er forsigtige med det, relateret til sikkerhed, inkonsekvent support i Windows API'erne i \? \ Syntaxen og appkompatibiliteten.



Det er en 3-delt serie og forklarer nogle få grunde til, at API'en er den måde, den er, og hvorfor begrænsningen er der.