Fájlútvonal-formátumok Windows-rendszereken

A névtér számos típusának System.IO tagjai olyan paramétert path tartalmaznak, amely lehetővé teszi egy fájlrendszer-erőforrás abszolút vagy relatív elérési útját. Ez az elérési út ezután a Windows fájlrendszer API-inak lesz átadva. Ez a témakör a Windows rendszereken használható fájlelérési utak formátumait ismerteti.

Hagyományos DOS-útvonalak

A szabványos DOS-elérési utak három összetevőből állhatnak:

  • Egy kötet- vagy meghajtóbetűjel, amelyet a kötetelválasztó (:) követ.
  • Könyvtárnév. A címtárelválasztó karakter elválasztja az alkönyvtárakat a beágyazott címtárhierarchián belül.
  • Nem kötelező fájlnév. A könyvtárelválasztó karakter elválasztja a fájl elérési útját és a fájlnevet.

Ha mindhárom összetevő jelen van, az elérési út abszolút. Ha nincs megadva kötet- vagy meghajtóbetűjel, és a címtár neve a könyvtárelválasztó karakterrel kezdődik, az elérési út az aktuális meghajtó gyökerétől relatív. Ellenkező esetben az elérési út az aktuális könyvtárhoz viszonyítva van. Az alábbi táblázat néhány lehetséges könyvtár- és fájlelérési útvonalat mutat be.

Elérési út Leírás
C:\Documents\Newsletters\Summer2018.pdf Abszolút fájl elérési útja a meghajtó C:gyökerétől.
\Program Files\Custom Utilities\StringFinder.exe Relatív elérési út az aktuális meghajtó gyökerétől.
2018\January.xlsx Az aktuális könyvtár alkönyvtárában lévő fájl relatív elérési útja.
..\Publications\TravelBrochure.pdf Egy könyvtárban lévő fájl relatív elérési útja az aktuális könyvtártól kezdve.
C:\Projects\apilibrary\apilibrary.sln Egy fájl abszolút elérési útja a meghajtó C:gyökeréből.
C:Projects\apilibrary\apilibrary.sln Relatív elérési út a meghajtó aktuális könyvtárából C: .

Fontos

Figyelje meg az utolsó két elérési út közötti különbséget. Mindkettő megadja az opcionális kötetkijelölőt (C: mindkét esetben), de az első a megadott kötet gyökerével kezdődik, míg a második nem. Ennek eredményeképpen az első egy abszolút elérési út a meghajtó C:gyökérkönyvtárából, míg a második a meghajtó C:aktuális könyvtárából származó relatív elérési út. A második űrlap használata, amikor az elsőt szánják, gyakori hibaforrás, amely windowsos fájlelérési utakat is magában foglal.

A metódus meghívásával Path.IsPathFullyQualified meghatározhatja, hogy egy fájl elérési útja teljes mértékben minősített-e (vagyis hogy az elérési út független-e az aktuális könyvtártól, és nem változik-e, amikor az aktuális könyvtár megváltozik). Vegye figyelembe, hogy az ilyen elérési utak tartalmazhatnak relatív könyvtárszegmenseket (. és ..) és továbbra is teljes mértékben minősíthetők, ha a feloldott elérési út mindig ugyanarra a helyre mutat.

Az alábbi példa az abszolút és a relatív elérési utak közötti különbséget szemlélteti. Feltételezi, hogy a könyvtár D:\FY2018\ létezik, és hogy a példa futtatása előtt nem állított be aktuális könyvtárat D:\ a parancssorból.

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-elérési utak

A hálózati erőforrások eléréséhez használt univerzális elnevezési konvenciós (UNC) elérési utak formátuma a következő:

  • Egy kiszolgáló vagy gazdagép neve, amelyet a program előtagként ad meg \\. A kiszolgáló neve lehet NetBIOS-gépnév vagy IP/FQDN-cím (az IPv4 és a v6 is támogatott).
  • A megosztás neve, amely elválasztja a gazdagép nevét.\ A kötetet együtt a kiszolgáló és a megosztás neve alkotja.
  • Könyvtárnév. A címtárelválasztó karakter elválasztja az alkönyvtárakat a beágyazott címtárhierarchián belül.
  • Nem kötelező fájlnév. A könyvtárelválasztó karakter elválasztja a fájl elérési útját és a fájlnevet.

Az alábbiakban néhány példát láthat az UNC-elérési utakra:

Elérési út Leírás
\\system07\C$\ A meghajtó gyökérkönyvtára a C: következőn system07: .
\\Server2\Share\Test\Foo.txt A Foo.txt kötet Teszt könyvtárában \\Server2\Share található fájl.

Az UNC-útvonalaknak mindig teljes mértékben minősítettnek kell lenniük. Tartalmazhatnak relatív könyvtárszegmenseket (. és ..), de ezeknek egy teljes elérési út részét kell képezniük. Relatív elérési utakat csak egy UNC-elérési út meghajtóbetűjelhez való leképezésével használhat.

DOS-eszköz elérési útjai

A Windows operációs rendszer egységes objektummodellt tartalmaz, amely az összes erőforrásra mutat, beleértve a fájlokat is. Ezek az objektumelérési utak a konzolablakból érhetők el, és a Win32 réteg számára egy speciális, szimbolikus hivatkozásokat tartalmazó mappán keresztül jelennek meg, amelyekhez az örökölt DOS- és UNC-elérési utak vannak leképezve. Ez a speciális mappa a DOS-eszköz elérési útjának szintaxisával érhető el, amely az alábbiak egyike:

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

A meghajtók meghajtóbetűjellel való azonosítása mellett a kötet guid azonosítójával is azonosíthatja a kötetet. Ez a következő formában jelenik meg:

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

Feljegyzés

A DOS-eszközút szintaxisa támogatott a Windows rendszeren futó .NET-implementációkban a .NET Core 1.1-től és a .NET-keretrendszer 4.6.2-től kezdve.

A DOS-eszköz elérési útja a következő összetevőkből áll:

  • Az eszköz elérési útjának megjelölője (\\.\ vagy \\?\), amely DOS-eszközútvonalként azonosítja az elérési utat.

    Feljegyzés

    A \\?\ .NET Core és a .NET 5+ minden verziójában támogatott, és .NET-keretrendszer a 4.6.2-es verziótól kezdve.

  • Szimbolikus hivatkozás a "valódi" eszközobjektumra (C: meghajtónév esetén, kötetazonosító esetén kötet{b75e2c83-0000-0000-0000-0000-602f0000000}

    A DOS-eszköz elérési útjának első szegmense az eszköz elérési útja után azonosítja a kötetet vagy a meghajtót. (Például és \\?\C:\\\.\BootPartition\.)

    Van egy konkrét hivatkozás a UNC-khez, amelyeket nem meglepő módon UNChívunk. Példa:

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

    Az eszköz UNCs-jai esetében a kiszolgáló/megosztás rész alkotja a kötetet. A kiszolgáló \\?\server1\utilities\\filecomparer\/megosztás rész server1\utilitiespéldául a következő: . Ez a relatív könyvtárszegmensekhez hasonló Path.GetFullPath(String, String) metódusok meghívásakor jelentős; soha nem lehet lépkedni a köteten.

A DOS-eszköz elérési útjai definíció szerint teljes mértékben minősítettek, és nem kezdődhetnek relatív könyvtárszegmenssel (. vagy ..). A jelenlegi könyvtárak soha nem lépnek be a használatukba.

Példa: Ugyanahhoz a fájlhoz való hivatkozás módjai

Az alábbi példa bemutatja, hogyan hivatkozhat egy fájlra az API-k névtérben System.IO való használatakor. A példa létrehoz egy FileInfo objektumot, és annak Name és Length tulajdonságainak használatával jeleníti meg a fájlnevet és a fájl hosszát.

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

Elérési út normalizálása

A Windows API-knak átadott útvonalak szinte mindegyike normalizálva van. A normalizálás során a Windows a következő lépéseket hajtja végre:

  • Azonosítja az elérési utat.
  • Az aktuális könyvtárat részben minősített (relatív) elérési utakra alkalmazza.
  • Az összetevők és a címtárelválasztók canonicalizálása.
  • Kiértékeli a relatív könyvtárösszetevőket (. az aktuális könyvtárhoz és .. a szülőkönyvtárhoz).
  • Levág bizonyos karaktereket.

Ez a normalizálás implicit módon történik, de explicit módon is elvégezhető a Path.GetFullPath metódus meghívásával, amely a GetFullPathName() függvény hívását burkolja. A Windows GetFullPathName() függvényt közvetlenül a P/Invoke használatával is meghívhatja.

Az elérési út azonosítása

Az elérési út normalizálásának első lépése az elérési út típusának azonosítása. Az útvonalak néhány kategória egyikébe tartoznak:

  • Ezek eszközútvonalak; vagyis két elválasztójellel és kérdőjellel vagy ponttal (\\? vagy \\.) kezdődnek.
  • Ezek UNC elérési utak; vagyis két elválasztójellel kezdődnek kérdőjel vagy pont nélkül.
  • Ezek teljes mértékben minősített DOS-útvonalak; vagyis egy meghajtóbetűjellel, egy kötetelválasztóval és egy összetevőelválasztóval (C:\) kezdődnek.
  • Egy örökölt eszközt (CON, LPT1).
  • Ezek az aktuális meghajtó gyökeréhez viszonyítva vannak; vagyis egyetlen összetevőelválasztóval (\) kezdődnek.
  • Ezek egy adott meghajtó aktuális könyvtárához viszonyítva vannak; vagyis egy meghajtóbetűjellel, egy kötetelválasztóval és egy összetevőelválasztóval (C:) kezdődnek.
  • Ezek az aktuális könyvtárhoz viszonyítva vannak; vagyis bármi mással kezdődnek (temp\testfile.txt).

Az elérési út típusa határozza meg, hogy a rendszer valamilyen módon alkalmazza-e az aktuális könyvtárat. Azt is meghatározza, hogy mi az elérési út "gyökere".

Örökölt eszközök kezelése

Ha az elérési út egy régi DOS-eszköz, például CON, COM1vagy LPT1, akkor az előerősítéssel és visszaadással \\.\ átalakítja eszközútvonallá.

Az örökölt eszköznévvel kezdődő elérési utakat a metódus mindig örökölt eszközként értelmezi Path.GetFullPath(String) . A DOS-eszköz elérési útja például az \\.\CON, és a DOS-eszköz elérési útjaCOM1.TXT\file1.txt.\\.\COM1CON.TXT

Az aktuális könyvtár alkalmazása

Ha egy elérési út nincs teljes mértékben minősítve, a Windows az aktuális könyvtárat alkalmazza rá. A UNC-k és az eszköz elérési útjai nem rendelkeznek az aktuális könyvtárral. A teljes meghajtó sem rendelkezik elválasztójellel C:\.

Ha az elérési út egyetlen összetevőelválasztóval kezdődik, a rendszer az aktuális könyvtárból származó meghajtót alkalmazza. Ha például a fájl elérési útja és \utilities az aktuális könyvtár, C:\temp\a normalizálás létrehozza a következőt C:\utilities:

Ha az elérési út meghajtóbetűjellel, kötetelválasztóval és összetevőelválasztó nélkül kezdődik, a rendszer a megadott meghajtó parancshéjából beállított utolsó aktuális könyvtárat alkalmazza. Ha az utolsó aktuális könyvtár nincs beállítva, a rendszer csak a meghajtót alkalmazza. Ha például a fájl elérési útja, D:sourcesakkor az aktuális könyvtár, C:\Documents\a D meghajtó utolsó aktuális könyvtára pedig az voltD:\sources\, az eredmény.D:\sources\sources Ezek a "meghajtó relatív" elérési útjai gyakori program- és szkriptlogika-hibák forrása. Feltételezve, hogy egy betűvel és kettősponttal kezdődő elérési út nem relatív, nyilvánvalóan nem helyes.

Ha az elérési út nem elválasztóval kezdődik, a rendszer az aktuális meghajtót és az aktuális könyvtárat alkalmazza. Ha például az elérési út és filecompare az aktuális könyvtár, C:\utilities\az eredmény az C:\utilities\filecompare\.

Fontos

A relatív elérési utak veszélyesek a többszálú alkalmazásokban (vagyis a legtöbb alkalmazásban), mert az aktuális könyvtár folyamatonkénti beállítás. Bármelyik szál bármikor módosíthatja az aktuális könyvtárat. A .NET Core 2.1-től kezdve meghívhatja azt a Path.GetFullPath(String, String) metódust, amely abszolút elérési utat kér le egy relatív elérési útból és a feloldani kívánt alap elérési útból (az aktuális könyvtárból).

Elválasztók canonicalizálása

A rendszer minden perjelet (/) szabványos Windows-elválasztóvá alakít, a fordított perjelet (\). Ha ezek jelen vannak, az első két perjelet követő perjelek sorozata egyetlen perjelbe van összecsukva.

Relatív összetevők kiértékelése

Az elérési út feldolgozása során a rendszer kiértékel minden olyan összetevőt vagy szegmenst, amely egy vagy két pontból (. vagy ..) áll:

  • Egyetlen időszakra az aktuális szegmens el lesz távolítva, mivel az az aktuális könyvtárra hivatkozik.

  • Dupla időszak esetén a rendszer eltávolítja az aktuális szegmenst és a szülőszegmenst, mivel a dupla időszak a szülőkönyvtárra hivatkozik.

    A szülőkönyvtárak csak akkor lesznek eltávolítva, ha nem tették meg az elérési út gyökerét. Az elérési út gyökere az elérési út típusától függ. Ez a DOS-elérési utak meghajtója (C:\) , a UNC-k kiszolgálója/megosztása (\\Server\Share), valamint az eszköz elérési útjainak (\\?\ vagy \\.\) eszközútvonal-előtagja.

Karakterek vágása

A korábban eltávolított elválasztójelek és relatív szegmensek futtatása mellett néhány további karakter is törlődik a normalizálás során:

  • Ha egy szegmens egyetlen időszakra végződik, az adott időszak el lesz távolítva. (Az előző lépésben egy vagy két időszak egy szegmense normalizálódik. A három vagy több pontból álló szegmens nincs normalizálva, és valójában érvényes fájl-/könyvtárnév.)

  • Ha az elérési út nem egy elválasztóban végződik, a rendszer eltávolítja az összes záró pontot és szóközt (U+0020). Ha az utolsó szegmens egyszerűen egy vagy két időszak, akkor a fenti relatív összetevők szabálya alá tartozik.

    Ez a szabály azt jelenti, hogy egy záró szóközzel rendelkező címtárnevet úgy hozhat létre, hogy egy záró elválasztót ad hozzá a szóköz után.

    Fontos

    Soha ne hozzon létre záró szóközzel rendelkező könyvtárat vagy fájlnevet. A záró szóközök megnehezíthetik vagy lehetetlenné tehetik a címtárak elérését, és az alkalmazások gyakran sikertelenek lesznek, ha olyan könyvtárakat vagy fájlokat próbálnak kezelni, amelyeknek a neve záró szóközöket tartalmaz.

Normalizálás kihagyása

A Windows API-nak átadott elérési utak általában (gyakorlatilag) átadva vannak a GetFullPathName függvénynek , és normalizálva vannak. Van egy fontos kivétel: egy eszközútvonal, amely pont helyett kérdőjellel kezdődik. Hacsak az elérési út nem pontosan a következővel \\?\ kezdődik (vegye figyelembe a canonical backslash használatát), akkor normalizálódik.

Miért szeretné kihagyni a normalizálást? Három fő oka van:

  1. Olyan útvonalakhoz való hozzáféréshez, amelyek általában nem érhetők el, de legálisak. Egy fájl vagy könyvtár például hidden.más módon nem érhető el.

  2. A teljesítmény javítása a normalizálás kihagyásával, ha már normalizálódott.

  3. Ha csak .NET-keretrendszer szeretné kihagyni a 259 karakternél hosszabb elérési utakat, hagyja ki az MAX_PATH elérési út hosszának ellenőrzését. A legtöbb API ezt engedélyezi, néhány kivétellel.

Feljegyzés

A .NET Core és a .NET 5+ implicit módon kezeli a hosszú útvonalakat, és nem végez MAX_PATH ellenőrzést. Az MAX_PATH ellenőrzés csak a .NET-keretrendszer vonatkozik.

A normalizálás kihagyása és az útvonal-ellenőrzések maximális száma az egyetlen különbség a két eszközútvonal-szintaxis között; egyébként azonosak. Legyen óvatos a normalizálás kihagyásával, mivel könnyen létrehozhat olyan útvonalakat, amelyekkel a "normál" alkalmazások nehezen kezelhetők.

A kezdő \\?\ útvonalak továbbra is normalizálódnak, ha explicit módon továbbítja őket a GetFullPathName függvénynek.

A GetFullPathName-nek karakternél MAX_PATH több elérési utat adhat át anélkül\\?\, hogy a getFullPathName nevet választja. Tetszőleges hosszúságú elérési utakat támogat a Windows által kezelhető maximális sztringméretig.

Eset és a Windows fájlrendszer

A Windows fájlrendszer sajátossága, hogy a nem Windows-felhasználók és fejlesztők zavarónak találják, hogy az elérési út és a címtárnevek nem érzéketlenek. Ez azt jelzi, hogy a címtár- és fájlnevek a létrehozásukkor használt sztringek burkolatát tükrözik. Például a metódushívás

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

Létrehoz egy TeStDiReCtOrY nevű könyvtárat. Ha átnevez egy könyvtárat vagy fájlt, hogy megváltoztassa az esetét, a könyvtár vagy a fájlnév az átnevezésekor használt sztring esetét tükrözi. Az alábbi kód például átnevez egy test.txt nevű fájlt 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

A címtár- és fájlnév-összehasonlítások azonban nem érzéketlenek. Ha "test.txt" nevű fájlt keres, a .NET fájlrendszer API-k figyelmen kívül hagyják a kis- és nagybetűket. A "Test.txt", a "TEST.TXT", a "test.TXT" és a kis- és nagybetűk bármely más kombinációja megegyezik a "test.txt"-tal.