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 Example2
{
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(Assembly.GetExecutingAssembly().Location, UriKind.Absolute);
string commandLine = $"/C cd D:\\FY2018 & \"{currentExe.LocalPath}\" stop";
ProcessStartInfo psi = new("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.IO
Imports System.Reflection
Public Module Example2
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
UNC
hí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észserver1\utilities
pé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" };
foreach (string filename in filenames)
{
FileInfo fi = new(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
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"}
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
, COM1
vagy LPT1
, akkor az előerősítéssel és visszaadással \\.\
átalakítja eszközútvonallá.
A Windows 11 előtt az örökölt eszköznévvel kezdődő elérési utakat a Path.GetFullPath(String) metódus mindig örökölt eszközként értelmezi. 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
.\\.\COM1
CON.TXT
Mivel ez már nem vonatkozik a Windows 11-re, adja meg az örökölt DOS-eszköz teljes elérési útját, például \\.\CON
.
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:sources
akkor 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.
Feljegyzés
A Unix-alapú operációs rendszereken futó .NET 8-tól kezdve a futtatókörnyezet már nem konvertálja vissza a perjel\
() karaktereket könyvtárelválasztókká (perjelek /
). További információ: Fordított perjel leképezése a Unix-fájl elérési útjaiban.
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:
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.A teljesítmény javítása a normalizálás kihagyásával, ha már normalizálódott.
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 Example3
{
static void Main()
{
var fi = new FileInfo(@".\test.txt");
fi.MoveTo(@".\Test.txt");
}
}
Imports System.IO
Module Example3
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.