Bestandspadindelingen op Windows-systemen

Leden van veel van de typen in de System.IO naamruimte bevatten een path parameter waarmee u een absoluut of relatief pad naar een bestandssysteemresource kunt opgeven. Dit pad wordt vervolgens doorgegeven aan Windows-bestandssysteem-API's. In dit onderwerp worden de indelingen voor bestandspaden besproken die u op Windows-systemen kunt gebruiken.

Traditionele DOS-paden

Een standaard DOS-pad kan bestaan uit drie onderdelen:

  • Een volume- of stationsletter gevolgd door het volumescheidingsteken (:).
  • Een mapnaam. Het adreslijstscheidingsteken scheidt submappen binnen de geneste maphiërarchie.
  • Een optionele bestandsnaam. Het mapscheidingsteken scheidt het bestandspad en de bestandsnaam.

Als alle drie de onderdelen aanwezig zijn, is het pad absoluut. Als er geen volume- of stationsletter is opgegeven en de mapnaam begint met het adreslijstscheidingsteken, is het pad relatief van de hoofdmap van het huidige station. Anders is het pad relatief ten opzichte van de huidige map. In de volgende tabel ziet u enkele mogelijke map- en bestandspaden.

Pad Beschrijving
C:\Documents\Newsletters\Summer2018.pdf Een absoluut bestandspad uit de hoofdmap van het station C:.
\Program Files\Custom Utilities\StringFinder.exe Een relatief pad uit de hoofdmap van het huidige station.
2018\January.xlsx Een relatief pad naar een bestand in een submap van de huidige map.
..\Publications\TravelBrochure.pdf Een relatief pad naar een bestand in een map die begint vanuit de huidige map.
C:\Projects\apilibrary\apilibrary.sln Een absoluut pad naar een bestand vanaf de hoofdmap van het station C:.
C:Projects\apilibrary\apilibrary.sln Een relatief pad uit de huidige map van het C: station.

Belangrijk

Let op het verschil tussen de laatste twee paden. Beide geven de optionele volumeaanduiding (C: in beide gevallen) op, maar de eerste begint met de hoofdmap van het opgegeven volume, terwijl de tweede niet. Als gevolg hiervan is de eerste een absoluut pad van de hoofdmap van C:station, terwijl de tweede een relatief pad is van de huidige map van station C:. Gebruik van het tweede formulier wanneer het eerste is bedoeld, is een veelvoorkomende bron van fouten die betrekking hebben op Windows-bestandspaden.

U kunt bepalen of een bestandspad volledig is gekwalificeerd (als het pad onafhankelijk is van de huidige map en niet verandert wanneer de huidige map wordt gewijzigd) door de Path.IsPathFullyQualified methode aan te roepen. Houd er rekening mee dat een dergelijk pad relatieve mapsegmenten (. en ..) kan bevatten en nog steeds volledig kan worden gekwalificeerd als het opgeloste pad altijd naar dezelfde locatie verwijst.

In het volgende voorbeeld ziet u het verschil tussen absolute en relatieve paden. Hierbij wordt ervan uitgegaan dat de map D:\FY2018\ bestaat en dat u geen huidige map D:\ hebt ingesteld vanaf de opdrachtprompt voordat u het voorbeeld uitvoert.

using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;

public class Example
{
   public static void Main(string[] args)
   {
      Console.WriteLine($"Current directory is '{Environment.CurrentDirectory}'");
      Console.WriteLine("Setting current directory to 'C:\\'");

      Directory.SetCurrentDirectory(@"C:\");
      string path = Path.GetFullPath(@"D:\FY2018");
      Console.WriteLine($"'D:\\FY2018' resolves to {path}");
      path = Path.GetFullPath(@"D:FY2018");
      Console.WriteLine($"'D:FY2018' resolves to {path}");

      Console.WriteLine("Setting current directory to 'D:\\Docs'");
      Directory.SetCurrentDirectory(@"D:\Docs");

      path = Path.GetFullPath(@"D:\FY2018");
      Console.WriteLine($"'D:\\FY2018' resolves to {path}");
      path = Path.GetFullPath(@"D:FY2018");

      // This will be "D:\Docs\FY2018" as it happens to match the drive of the current directory
      Console.WriteLine($"'D:FY2018' resolves to {path}");

      Console.WriteLine("Setting current directory to 'C:\\'");
      Directory.SetCurrentDirectory(@"C:\");

      path = Path.GetFullPath(@"D:\FY2018");
      Console.WriteLine($"'D:\\FY2018' resolves to {path}");

      // This will be either "D:\FY2018" or "D:\FY2018\FY2018" in the subprocess. In the sub process,
      // the command prompt set the current directory before launch of our application, which
      // sets a hidden environment variable that is considered.
      path = Path.GetFullPath(@"D:FY2018");
      Console.WriteLine($"'D:FY2018' resolves to {path}");

      if (args.Length < 1)
      {
         Console.WriteLine(@"Launching again, after setting current directory to D:\FY2018");
         Uri currentExe = new Uri(Assembly.GetExecutingAssembly().GetName().CodeBase, UriKind.Absolute);
         string commandLine = $"/C cd D:\\FY2018 & \"{currentExe.LocalPath}\" stop";
         ProcessStartInfo psi = new ProcessStartInfo("cmd", commandLine); ;
         Process.Start(psi).WaitForExit();

         Console.WriteLine("Sub process returned:");
         path = Path.GetFullPath(@"D:\FY2018");
         Console.WriteLine($"'D:\\FY2018' resolves to {path}");
         path = Path.GetFullPath(@"D:FY2018");
         Console.WriteLine($"'D:FY2018' resolves to {path}");
      }
      Console.WriteLine("Press any key to continue... ");
      Console.ReadKey();
   }
}
// The example displays the following output:
//      Current directory is 'C:\Programs\file-paths'
//      Setting current directory to 'C:\'
//      'D:\FY2018' resolves to D:\FY2018
//      'D:FY2018' resolves to d:\FY2018
//      Setting current directory to 'D:\Docs'
//      'D:\FY2018' resolves to D:\FY2018
//      'D:FY2018' resolves to D:\Docs\FY2018
//      Setting current directory to 'C:\'
//      'D:\FY2018' resolves to D:\FY2018
//      'D:FY2018' resolves to d:\FY2018
//      Launching again, after setting current directory to D:\FY2018
//      Sub process returned:
//      'D:\FY2018' resolves to D:\FY2018
//      'D:FY2018' resolves to d:\FY2018
// The subprocess displays the following output:
//      Current directory is 'C:\'
//      Setting current directory to 'C:\'
//      'D:\FY2018' resolves to D:\FY2018
//      'D:FY2018' resolves to D:\FY2018\FY2018
//      Setting current directory to 'D:\Docs'
//      'D:\FY2018' resolves to D:\FY2018
//      'D:FY2018' resolves to D:\Docs\FY2018
//      Setting current directory to 'C:\'
//      'D:\FY2018' resolves to D:\FY2018
//      'D:FY2018' resolves to D:\FY2018\FY2018
Imports System.Diagnostics
Imports System.IO
Imports System.Reflection

Public Module Example

    Public Sub Main(args() As String)
        Console.WriteLine($"Current directory is '{Environment.CurrentDirectory}'")
        Console.WriteLine("Setting current directory to 'C:\'")
        Directory.SetCurrentDirectory("C:\")

        Dim filePath As String = Path.GetFullPath("D:\FY2018")
        Console.WriteLine($"'D:\\FY2018' resolves to {filePath}")
        filePath = Path.GetFullPath("D:FY2018")
        Console.WriteLine($"'D:FY2018' resolves to {filePath}")

        Console.WriteLine("Setting current directory to 'D:\\Docs'")
        Directory.SetCurrentDirectory("D:\Docs")

        filePath = Path.GetFullPath("D:\FY2018")
        Console.WriteLine($"'D:\\FY2018' resolves to {filePath}")
        filePath = Path.GetFullPath("D:FY2018")

        ' This will be "D:\Docs\FY2018" as it happens to match the drive of the current directory
        Console.WriteLine($"'D:FY2018' resolves to {filePath}")

        Console.WriteLine("Setting current directory to 'C:\\'")
        Directory.SetCurrentDirectory("C:\")

        filePath = Path.GetFullPath("D:\FY2018")
        Console.WriteLine($"'D:\\FY2018' resolves to {filePath}")

        ' This will be either "D:\FY2018" or "D:\FY2018\FY2018" in the subprocess. In the sub process,
        ' the command prompt set the current directory before launch of our application, which
        ' sets a hidden environment variable that is considered.
        filePath = Path.GetFullPath("D:FY2018")
        Console.WriteLine($"'D:FY2018' resolves to {filePath}")

        If args.Length < 1 Then
            Console.WriteLine("Launching again, after setting current directory to D:\FY2018")
            Dim currentExe As New Uri(Assembly.GetExecutingAssembly().GetName().CodeBase, UriKind.Absolute)
            Dim commandLine As String = $"/C cd D:\FY2018 & ""{currentExe.LocalPath}"" stop"
            Dim psi As New ProcessStartInfo("cmd", commandLine)
            Process.Start(psi).WaitForExit()

            Console.WriteLine("Sub process returned:")
            filePath = Path.GetFullPath("D:\FY2018")
            Console.WriteLine($"'D:\\FY2018' resolves to {filePath}")
            filePath = Path.GetFullPath("D:FY2018")
            Console.WriteLine($"'D:FY2018' resolves to {filePath}")
        End If
        Console.WriteLine("Press any key to continue... ")
        Console.ReadKey()
    End Sub
End Module
' The example displays the following output:
'      Current directory is 'C:\Programs\file-paths'
'      Setting current directory to 'C:\'
'      'D:\FY2018' resolves to D:\FY2018
'      'D:FY2018' resolves to d:\FY2018
'      Setting current directory to 'D:\Docs'
'      'D:\FY2018' resolves to D:\FY2018
'      'D:FY2018' resolves to D:\Docs\FY2018
'      Setting current directory to 'C:\'
'      'D:\FY2018' resolves to D:\FY2018
'      'D:FY2018' resolves to d:\FY2018
'      Launching again, after setting current directory to D:\FY2018
'      Sub process returned:
'      'D:\FY2018' resolves to D:\FY2018
'      'D:FY2018' resolves to d:\FY2018
' The subprocess displays the following output:
'      Current directory is 'C:\'
'      Setting current directory to 'C:\'
'      'D:\FY2018' resolves to D:\FY2018
'      'D:FY2018' resolves to D:\FY2018\FY2018
'      Setting current directory to 'D:\Docs'
'      'D:\FY2018' resolves to D:\FY2018
'      'D:FY2018' resolves to D:\Docs\FY2018
'      Setting current directory to 'C:\'
'      'D:\FY2018' resolves to D:\FY2018
'      'D:FY2018' resolves to D:\FY2018\FY2018

UNC-paden

UNC-paden (Universal Naming Convention), die worden gebruikt voor toegang tot netwerkbronnen, hebben de volgende indeling:

  • Een server- of hostnaam, die voorafgegaan wordt door \\. De servernaam kan een NetBIOS-computernaam zijn of een IP-/FQDN-adres (IPv4 en v6 worden ondersteund).
  • Een sharenaam, die is gescheiden van de hostnaam door \. Samen vormen de server en de sharenaam het volume.
  • Een mapnaam. Het adreslijstscheidingsteken scheidt submappen binnen de geneste maphiërarchie.
  • Een optionele bestandsnaam. Het mapscheidingsteken scheidt het bestandspad en de bestandsnaam.

Hier volgen enkele voorbeelden van UNC-paden:

Pad Beschrijving
\\system07\C$\ De hoofdmap van het C: station op system07.
\\Server2\Share\Test\Foo.txt Het Foo.txt bestand in de map Test van het \\Server2\Share volume.

UNC-paden moeten altijd volledig zijn gekwalificeerd. Ze kunnen relatieve mapsegmenten (. en ..) bevatten, maar deze moeten deel uitmaken van een volledig gekwalificeerd pad. U kunt relatieve paden alleen gebruiken door een UNC-pad toe te passen aan een stationsletter.

DOS-apparaatpaden

Het Windows-besturingssysteem heeft een geïntegreerd objectmodel dat verwijst naar alle resources, inclusief bestanden. Deze objectpaden zijn toegankelijk vanuit het consolevenster en worden blootgesteld aan de Win32-laag via een speciale map met symbolische koppelingen waaraan verouderde DOS- en UNC-paden zijn toegewezen. Deze speciale map wordt geopend via de syntaxis van het DOS-apparaatpad. Dit is een van de volgende:

\\.\C:\Test\Foo.txt \\?\C:\Test\Foo.txt

Naast het identificeren van een station met de stationsletter, kunt u een volume identificeren met behulp van de volume-GUID. Dit heeft de volgende vorm:

\\.\Volume{b75e2c83-0000-0000-0000-602f00000000}\Test\Foo.txt \\?\Volume{b75e2c83-0000-0000-0000-602f00000000}\Test\Foo.txt

Notitie

DoS-apparaatpadsyntaxis wordt ondersteund in .NET-implementaties die worden uitgevoerd in Windows vanaf .NET Core 1.1 en .NET Framework 4.6.2.

Het DOS-apparaatpad bestaat uit de volgende onderdelen:

  • De apparaatpadaanduiding (\\.\ of \\?\), waarmee het pad wordt geïdentificeerd als een DOS-apparaatpad.

    Notitie

    De \\?\ wordt ondersteund in alle versies van .NET Core en .NET 5+ en in .NET Framework vanaf versie 4.6.2.

  • Een symbolische koppeling naar het 'echte' apparaatobject (C: in het geval van een stationsnaam of Volume{b75e2c83-0000-0000-0000-602f00000000} in het geval van een volume-GUID).

    Het eerste segment van het DOS-apparaatpad nadat de aanduiding voor het apparaatpad het volume of station identificeert. (Bijvoorbeeld \\?\C:\ , en \\.\BootPartition\.)

    Er is een specifieke koppeling voor UNC's die worden aangeroepen, niet verrassend, UNC. Voorbeeld:

    \\.\UNC\Server\Share\Test\Foo.txt \\?\UNC\Server\Share\Test\Foo.txt

    Voor apparaat-UNC's vormt het server-/sharegedeelte het volume. In het \\?\server1\utilities\\filecomparer\gedeelte server/share is server1\utilitieshet bijvoorbeeld . Dit is belangrijk wanneer u een methode aanroept, zoals Path.GetFullPath(String, String) met relatieve adreslijstsegmenten. Het is nooit mogelijk om voorbij het volume te navigeren.

DOS-apparaatpaden zijn per definitie volledig gekwalificeerd en kunnen niet beginnen met een relatief mapsegment (. of ..). Huidige directory's voeren nooit hun gebruik in.

Voorbeeld: Manieren om naar hetzelfde bestand te verwijzen

In het volgende voorbeeld ziet u een aantal manieren waarop u naar een bestand kunt verwijzen wanneer u de API's in de System.IO naamruimte gebruikt. In het voorbeeld wordt een FileInfo object geïnstitueert en worden Name de eigenschappen gebruikt Length om de bestandsnaam en de lengte van het bestand weer te geven.

using System;
using System.IO;

class Program
{
    static void Main()
    {
        string[] filenames = {
            @"c:\temp\test-file.txt",
            @"\\127.0.0.1\c$\temp\test-file.txt",
            @"\\LOCALHOST\c$\temp\test-file.txt",
            @"\\.\c:\temp\test-file.txt",
            @"\\?\c:\temp\test-file.txt",
            @"\\.\UNC\LOCALHOST\c$\temp\test-file.txt",
            @"\\127.0.0.1\c$\temp\test-file.txt" };

        foreach (var filename in filenames)
        {
            FileInfo fi = new FileInfo(filename);
            Console.WriteLine($"file {fi.Name}: {fi.Length:N0} bytes");
        }
    }
}
// The example displays output like the following:
//      file test-file.txt: 22 bytes
//      file test-file.txt: 22 bytes
//      file test-file.txt: 22 bytes
//      file test-file.txt: 22 bytes
//      file test-file.txt: 22 bytes
//      file test-file.txt: 22 bytes
//      file test-file.txt: 22 bytes
Imports System.IO

Module Program
    Sub Main()
        Dim filenames() As String = {
                "c:\temp\test-file.txt",
                "\\127.0.0.1\c$\temp\test-file.txt",
                "\\LOCALHOST\c$\temp\test-file.txt",
                "\\.\c:\temp\test-file.txt",
                "\\?\c:\temp\test-file.txt",
                "\\.\UNC\LOCALHOST\c$\temp\test-file.txt",
                "\\127.0.0.1\c$\temp\test-file.txt"}

        For Each filename In filenames
            Dim fi As New FileInfo(filename)
            Console.WriteLine($"file {fi.Name}: {fi.Length:N0} bytes")
        Next
    End Sub
End Module

Padnormalisatie

Bijna alle paden die worden doorgegeven aan Windows-API's, worden genormaliseerd. Tijdens normalisatie voert Windows de volgende stappen uit:

  • Identificeert het pad.
  • Hiermee past u de huidige map toe op gedeeltelijk gekwalificeerde (relatieve) paden.
  • Canonicaliseert onderdelen en mapscheidingstekens.
  • Evalueert relatieve maponderdelen (. voor de huidige map en .. voor de bovenliggende map).
  • Hiermee worden bepaalde tekens geknipt.

Deze normalisatie gebeurt impliciet, maar u kunt dit expliciet doen door de Path.GetFullPath methode aan te roepen, waarmee een aanroep naar de functie GetFullPathName() wordt verpakt. U kunt de Functie Windows GetFullPathName() ook rechtstreeks aanroepen met behulp van P/Invoke.

Het pad identificeren

De eerste stap in padnormalisatie is het identificeren van het type pad. Paden vallen in een van de volgende categorieën:

  • Het zijn apparaatpaden; Dat wil gezegd: ze beginnen met twee scheidingstekens en een vraagteken of punt (\\? of \\.).
  • Het zijn UNC-paden; Dat wil gezegd: ze beginnen met twee scheidingstekens zonder vraagteken of punt.
  • Ze zijn volledig gekwalificeerde DOS-paden; Dat wil gezegd: ze beginnen met een stationsletter, een volumescheidingsteken en een onderdeelscheidingsteken (C:\).
  • Ze wijzen een verouderd apparaat (CON, LPT1) aan.
  • Ze zijn relatief ten opzichte van de hoofdmap van het huidige station; dat wil gezegd dat ze beginnen met één onderdeelscheidingsteken (\).
  • Ze zijn relatief ten opzichte van de huidige map van een opgegeven station; Dat wil gezegd: ze beginnen met een stationsletter, een volumescheidingsteken en geen onderdeelscheidingsteken (C:).
  • Ze zijn relatief ten opzichte van de huidige map; Dat wil zeggen, ze beginnen met iets anders (temp\testfile.txt).

Het type van het pad bepaalt of een huidige map op een of andere manier wordt toegepast. Het bepaalt ook wat de 'root' van het pad is.

Verouderde apparaten verwerken

Als het pad een verouderd DOS-apparaat is, zoals CON, COM1of LPT1, wordt het geconverteerd naar een apparaatpad door vooraf te \\.\ gaan en te retourneren.

Een pad dat begint met een verouderde apparaatnaam wordt altijd geïnterpreteerd als een verouderd apparaat door de Path.GetFullPath(String) methode. Het DOS-apparaatpad CON.TXT is bijvoorbeeld en \\.\CONhet DOS-apparaatpad COM1.TXT\file1.txt is \\.\COM1.

De huidige map toepassen

Als een pad niet volledig is gekwalificeerd, past Windows de huidige map hierop toe. UNC's en apparaatpaden hebben niet de huidige map toegepast. Geen van beide een volledig station met scheidingsteken C:\.

Als het pad begint met een scheidingsteken voor één onderdeel, wordt het station uit de huidige map toegepast. Als het bestandspad bijvoorbeeld is \utilities en de huidige map is C:\temp\, produceert C:\utilitiesnormalisatie .

Als het pad begint met een stationsletter, volumescheidingsteken en geen onderdeelscheidingsteken, wordt de laatste huidige mapset van de opdrachtshell voor het opgegeven station toegepast. Als de laatste huidige map niet is ingesteld, wordt het station alleen toegepast. Als het bestandspad bijvoorbeeld is D:sources, de huidige map is C:\Documents\en de laatste huidige map op station D: was D:\sources\, is D:\sources\sourceshet resultaat . Deze 'relatieve stationspaden' zijn een veelvoorkomende bron van programma- en scriptlogicafouten. Ervan uitgaande dat een pad dat begint met een letter en een dubbele punt niet relatief is, is duidelijk niet juist.

Als het pad begint met iets anders dan een scheidingsteken, worden het huidige station en de huidige map toegepast. Als het pad bijvoorbeeld is filecompare en de huidige map is C:\utilities\, is C:\utilities\filecompare\het resultaat .

Belangrijk

Relatieve paden zijn gevaarlijk in multithreaded toepassingen (dat wil gezegd, de meeste toepassingen) omdat de huidige map een instelling per proces is. Elke thread kan de huidige map op elk gewenst moment wijzigen. Vanaf .NET Core 2.1 kunt u de Path.GetFullPath(String, String) methode aanroepen om een absoluut pad op te halen van een relatief pad en het basispad (de huidige map) waarmee u deze wilt oplossen.

Scheidingstekens voor canonicaliseren

Alle slashes (/) worden geconverteerd naar het standaardscheidingsteken voor Windows, de back-slash (\). Als ze aanwezig zijn, wordt een reeks slashes die volgen op de eerste twee slash's samengevouwen tot één slash.

Relatieve onderdelen evalueren

Wanneer het pad wordt verwerkt, worden alle onderdelen of segmenten die bestaan uit één of twee perioden (. of ..) geëvalueerd:

  • Voor één periode wordt het huidige segment verwijderd, omdat het verwijst naar de huidige map.

  • Voor een dubbele periode worden het huidige segment en het bovenliggende segment verwijderd, omdat de dubbele punt verwijst naar de bovenliggende map.

    Bovenliggende mappen worden alleen verwijderd als ze niet achter de hoofdmap van het pad liggen. De hoofdmap van het pad is afhankelijk van het type pad. Het is het station (C:\) voor DOS-paden, de server/share voor UNC's (\\Server\Share) en het voorvoegsel van het apparaatpad voor apparaatpaden (\\?\ of \\.\).

Tekens knippen

Naast de uitvoeringen van scheidingstekens en relatieve segmenten die eerder zijn verwijderd, worden enkele extra tekens verwijderd tijdens normalisatie:

  • Als een segment in één punt eindigt, wordt die periode verwijderd. (Een segment van een enkele of dubbele periode wordt genormaliseerd in de vorige stap. Een segment van drie of meer perioden wordt niet genormaliseerd en is in feite een geldige bestandsnaam/mapnaam.)

  • Als het pad niet eindigt op een scheidingsteken, worden alle volgperioden en spaties (U+0020) verwijderd. Als het laatste segment slechts één of dubbele punt is, valt het onder de bovenstaande relatieve onderdelenregel.

    Deze regel betekent dat u een mapnaam met een volgruimte kunt maken door een volgscheidingsteken toe te voegen na de spatie.

    Belangrijk

    Maak nooit een map of bestandsnaam met een volgruimte. Volgspaties kunnen het moeilijk of onmogelijk maken om toegang te krijgen tot een map en toepassingen mislukken meestal bij het verwerken van mappen of bestanden waarvan de namen volgspaties bevatten.

Normalisatie overslaan

Normaal gesproken wordt elk pad dat wordt doorgegeven aan een Windows-API (effectief) doorgegeven aan de functie GetFullPathName en genormaliseerd. Er is een belangrijke uitzondering: een apparaatpad dat begint met een vraagteken in plaats van een punt. Tenzij het pad precies \\?\ begint (let op het gebruik van de canonieke backslash), wordt het genormaliseerd.

Waarom wilt u normalisatie overslaan? Er zijn drie belangrijke redenen:

  1. Toegang krijgen tot paden die normaal gesproken niet beschikbaar zijn, maar legaal zijn. Een bestand of map met de naam hidden., bijvoorbeeld, is onmogelijk om op een andere manier toegang te krijgen.

  2. Om de prestaties te verbeteren door normalisatie over te slaan als u al genormaliseerd bent.

  3. Alleen in .NET Framework kunt u de controle op padlengte MAX_PATH overslaan om paden met meer dan 259 tekens toe te staan. De meeste API's staan dit toe, met enkele uitzonderingen.

Notitie

.NET Core en .NET 5+ verwerkt impliciet lange paden en voert geen controle uit MAX_PATH . De MAX_PATH controle is alleen van toepassing op .NET Framework.

Normalisatie- en maximale padcontroles overslaan is het enige verschil tussen de twee apparaatpadsyntaxis; ze zijn anders identiek. Wees voorzichtig met het overslaan van normalisatie, omdat u eenvoudig paden kunt maken die moeilijk zijn voor 'normale' toepassingen om mee te gaan.

Paden die beginnen met \\?\ worden nog steeds genormaliseerd als u ze expliciet doorgeeft aan de functie GetFullPathName.

U kunt paden van meer dan MAX_PATH tekens doorgeven aan GetFullPathName zonder \\?\. Het ondersteunt willekeurige lengtepaden tot de maximale tekenreeksgrootte die Door Windows kan worden verwerkt.

Case en het Windows-bestandssysteem

Een eigenaardigheid van het Windows-bestandssysteem dat niet-Windows-gebruikers en ontwikkelaars verwarrend vinden, is dat pad- en mapnamen niet hoofdlettergevoelig zijn. Dat wil gezegd, map- en bestandsnamen weerspiegelen het hoofdlettergebruik van de tekenreeksen die worden gebruikt bij het maken ervan. Bijvoorbeeld de methode-aanroep

Directory.Create("TeStDiReCtOrY");
Directory.Create("TeStDiReCtOrY")

maakt een map met de naam TeStDiReCtOrY. Als u de naam van een map of bestand wijzigt om het hoofdlettergebruik te wijzigen, geeft de map of bestandsnaam het geval weer van de tekenreeks die wordt gebruikt wanneer u de naam ervan wijzigt. Met de volgende code wordt bijvoorbeeld de naam van een bestand met de naam test.txt gewijzigd in Test.txt:

using System.IO;

class Example
{
   static void Main()
   {
      var fi = new FileInfo(@".\test.txt");
      fi.MoveTo(@".\Test.txt");
   }
}
Imports System.IO

Module Example
    Public Sub Main()
        Dim fi As New FileInfo(".\test.txt")
        fi.MoveTo(".\Test.txt")
    End Sub
End Module

Vergelijkingen van map- en bestandsnaam zijn echter niet hoofdlettergevoelig. Als u zoekt naar een bestand met de naam 'test.txt', negeren .NET-bestandssysteem-API's hoofdlettergebruik in de vergelijking. "Test.txt", "TEST.TXT", "test.TXT" en een andere combinatie van hoofdletters en kleine letters komt overeen met "test.txt".