Formate von Dateipfaden unter Windows-SystemenFile path formats on Windows systems

Die Member vieler Typen im System.IO-Namespace enthalten einen path-Parameter, mit dem Sie einen absoluten oder relativen Pfad zu einer Dateisystemressource festlegen können.Members of many of the types in the System.IO namespace include a path parameter that lets you specify an absolute or relative path to a file system resource. Dieser Pfad wird dann an Windows-Dateisystem-APIs übergeben.This path is then passed to Windows file system APIs. In diesem Artikel werden die Formate für Dateipfade erläutert, die Sie unter Windows-Systemen verwenden können.This topic discusses the formats for file paths that you can use on Windows systems.

Herkömmliche DOS-PfadeTraditional DOS paths

Ein standardmäßiger DOS-Pfad kann aus drei Komponenten bestehen:A standard DOS path can consist of three components:

  • Ein Volume oder Laufwerkbuchstabe gefolgt von dem entsprechenden Trennzeichen (:).A volume or drive letter followed by the volume separator (:).
  • Ein Verzeichnisname.A directory name. Das Verzeichnistrennzeichen trennt Unterverzeichnisse innerhalb der geschachtelten Verzeichnishierarchie.The directory separator character separates subdirectories within the nested directory hierarchy.
  • Ein optionaler Dateiname.An optional filename. Das Verzeichnistrennzeichen trennt den Dateipfad und den Dateinamen.The directory separator character separates the file path and the filename.

Wenn alle drei Komponenten vorhanden sind, ist der Pfad absolut.If all three components are present, the path is absolute. Wenn kein Volume oder Laufwerkbuchstabe angegeben ist und der Name des Verzeichnisses mit dem Verzeichnistrennzeichen beginnt, ist der Pfad relativ zum Stamm des aktuellen Laufwerks.If no volume or drive letter is specified and the directory name begins with the directory separator character, the path is relative from the root of the current drive. Andernfalls ist der Pfad relativ zum aktuellen Verzeichnis.Otherwise, the path is relative to the current directory. In der folgenden Tabelle werden mögliche Verzeichnis- und Dateipfade veranschaulicht.The following table shows some possible directory and file paths.

PfadPath BeschreibungDescription
C:\Documents\Newsletters\Summer2018.pdf Ein absoluter Dateipfad aus dem Stamm vom Laufwerk „C:“An absolute file path from the root of drive C:
\Program Files\Custom Utilities\StringFinder.exe Ein absoluter Pfad aus dem Stamm des aktuellen LaufwerksAn absolute path from the root of the current drive.
2018\January.xlsx Ein relativer Pfad zu einer Datei in einem Unterverzeichnis des aktuellen VerzeichnissesA relative path to a file in a subdirectory of the current directory.
..\Publications\TravelBrochure.pdf Ein relativer Pfad zu einer Datei in einem Verzeichnis, das ein Peer des aktuellen Verzeichnisses istA relative path to file in a directory that is a peer of the current directory.
C:\Projects\apilibrary\apilibrary.sln Ein absoluter Pfad zu einer Datei aus dem Stamm vom Laufwerk „C:“An absolute path to a file from the root of drive C:
C:Projects\apilibrary\apilibrary.sln Ein relativer Pfad aus dem aktuellen Verzeichnis des Laufwerks „C:“A relative path from the current directory of the C: drive.

Wichtig

Beachten Sie den Unterschied zwischen den letzten beiden Pfaden.Note the difference between the last two paths. Beide geben den optionalen Volumebezeichner (in beiden Fällen „C:“) an, jedoch beginnt der erste im Gegensatz zum zweiten mit dem Stamm des angegebenen Volume.Both specify the optional volume specifier (C: in both cases), but the first begins with the root of the specified volume, whereas the second does not. Daher ist der erste ein absoluter Pfad aus dem Stammverzeichnis vom Laufwerk „C:“, während der zweite ein relativer Pfad aus dem aktuellen Verzeichnis vom Laufwerk „C:“ ist.As result, the first is an absolute path from the root directory of drive C:, whereas the second is a relative path from the current directory of drive C:. Verwenden Sie das zweite Format, wenn das erste als Ursache für Fehler mit Windows-Dateipfaden bekannt ist.Use of the second form when the first is intended is a common source of bugs that involve Windows file paths.

Sie können ermitteln, ob ein Dateipfad absolut ist (d.h. der Pfad ist unabhängig vom aktuellen Verzeichnis und ändert sich nicht, wenn das aktuelle Verzeichnis geändert wird), indem Sie die Methode IsPathFullyQualified aufrufen.You can determine whether a file path is fully qualified (that is, it the path is independent of the current directory and does not change when the current directory changes) by calling the IsPathFullyQualified method. Beachten Sie, dass ein solcher Pfad relative Verzeichnissegmente (. und ..) enthalten und weiterhin absolut sein kann, wenn der aufgelöste Pfad immer zum gleichen Speicherort führt.Note that such a path can include relative directory segments (. and ..) and still be fully qualified if the resolved path always points to the same location.

Im folgenden Beispiel wird der Unterschied zwischen absoluten und relativen Pfaden veranschaulicht.The following example illustrates the difference between absolute and relative paths. Es wird davon ausgegangen, dass das Verzeichnis „D:\FY2018\“ vorhanden ist, und dass Sie kein aktuelles Verzeichnis für „D:\“ über die Eingabeaufforderung festgelegt haben, bevor Sie das Beispiel ausführen.It assumes that the directory D:\FY2018\ exists, and that you haven't set any curent directory for D:\ from the command prompt before running the example.

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-PfadeUNC paths

UNC-Pfade (Universal Naming Convention), die für den Zugriff auf Netzwerkressourcen verwendet werden, weisen das folgende Format auf:Universal naming convention (UNC) paths, which are used to access network resources, have the following format:

  • Ein Server- oder Hostname, dem \\ vorangestellt ist.A server or host name, which is prefaced by \\. Der Servername kann ein NetBIOS-Computername oder eine IP-/FQDN-Adresse sein (IPv4 und v6 werden unterstützt).The server name can be a NetBIOS machine name or an IP/FQDN address (IPv4 as well as v6 are supported).
  • Ein Freigabename, der durch \ vom Hostnamen getrennt wird.A share name, which is separated from the host name by \. Gemeinsam bilden der Server- und Freigabename das Volume.Together, the server and share name make up the volume.
  • Ein Verzeichnisname.A directory name. Das Verzeichnistrennzeichen trennt Unterverzeichnisse innerhalb der geschachtelten Verzeichnishierarchie.The directory separator character separates subdirectories within the nested directory hierarchy.
  • Ein optionaler Dateiname.An optional filename. Das Verzeichnistrennzeichen trennt den Dateipfad und den Dateinamen.The directory separator character separates the file path and the filename.

Im Folgenden werden einige Beispiele für UNC-Pfade aufgeführt:The following are some examples of UNC paths:

PfadPath BeschreibungDescription
\\system07\C$\ Das Stammverzeichnis des Laufwerks „C:“ auf system07.The root directory of the C: drive on system07.
\\Server2\Share\Test\Foo.txt Die Datei „Foo.txt“ im Testverzeichnis des Volume „\\Server2\Share“.The Foo.txt file in the Test directory of the \\Server2\Share volume.

UNC-Pfade müssen immer absolut sein.UNC paths must always be fully qualified. Sie können relative Verzeichnissegmente (. und ..) enthalten, jedoch müssen diese Teil eines absoluten Pfads sein.They can include relative directory segments (. and ..), but these must be part of a fully qualified path. Sie können relative Pfade nur verwenden, indem Sie einem Laufwerkbuchstaben einen UNC-Pfad zuordnen.You can use relative paths only by mapping a UNC path to a drive letter.

DOS-GerätepfadeDOS device paths

Das Windows-Betriebssystem verfügt über ein einheitliches Objektmodell, das auf alle Ressourcen, einschließlich Dateien, verweist.The Windows operating system has a unified object model that points to all resources, including files. Sie können über das Konsolenfenster auf diese Objektpfade zugreifen. Diese werden über einen speziellen Ordner aus symbolischen Verknüpfungen, denen ältere DOS- und UNC-Pfade zugeordnet sind, für die Win32-Schicht zur Verfügung gestellt.These object paths are accessible from the console window and are exposed to the Win32 layer through a special folder of symbolic links that legacy DOS and UNC paths are mapped to. Der Zugriff auf diesen speziellen Ordner erfolgt über die DOS-Gerätepfadsyntax, die einer der Folgenden entspricht:This special folder is accessed via the DOS device path syntax, which is one of:

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

Zusätzlich zum Identifizieren eines Laufwerks anhand des Laufwerkbuchstabens können Sie ein Volume mithilfe des Volume-GUID identifizieren.In addition to identifying a drive by its drive letter, you can identify a volume by using its volume GUID. Dieser weist folgendes Format auf:This takes the form:

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

Hinweis

Die DOS-Gerätepfadsyntax wird beginnend mit .NET Core 1.1 und .NET Framework 4.6.2 von .NET-Implementierungen unterstützt, die unter Windows ausgeführt werden.DOS device path syntax is supported on .NET implementations running on Windows starting with .NET Core 1.1 and .NET Framework 4.6.2.

Der DOS-Gerätepfad besteht aus den folgenden Komponenten:The DOS device path consists of the following components:

  • Der Gerätepfadbezeichner (\\.\ oder \\?\), der den Pfad als DOS-Gerätepfad identifiziert.The device path specifier (\\.\ or \\?\), which identifies the path as a DOS device path.

    Hinweis

    \\?\ wird in allen Versionen von .NET Core und ab Version 4.6.2 von .NET Framework unterstützt.The \\?\ is supported in all versions of .NET Core and in the .NET Framework starting with version 4.6.2.

  • Ein symbolischer Link zum „echten“ Geräteobjekt (im Fall eines Laufwerknamens „C:“, im Fall eines Volume-GUID „Volume{b75e2c83-0000-0000-0000-602f00000000}“).A symbolic link to the "real" device object (C: in the case of a drive name, or Volume{b75e2c83-0000-0000-0000-602f00000000} in the case of a volume GUID).

    Das erste Segment des DOS-Gerätepfads, nachdem der Gerätepfadbezeichner das Volume oder Laufwerk identifiziert.The first segment of the DOS device path after the device path specifier identifies the volume or drive. (Zum Beispiel \\?\C:\ und \\.\BootPartition\.)(For example, \\?\C:\ and \\.\BootPartition\.)

    Es gibt eine spezifische Verknüpfung für UNC-Pfade mit dem unverwechselbaren Namen UNC.There is a specific link for UNCs that is called, not surprisingly, UNC. Beispiel:For example:

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

    Bei Geräte-UNCs bildet der Abschnitt „server/share“ das Volume.For device UNCs, the server/share portion forms the volume. Zum Beispiel entspricht der Abschnitt „server/share“ bei \\?\server1\e:\utilities\\filecomparer\ „server1\utilities“.For example, in \\?\server1\e:\utilities\\filecomparer\, the server/share portion is server1\utilities. Dies ist beim Aufrufen einer Methode mit relativen Verzeichnissegmenten wie Path.GetFullPath(String, String) wichtig. Es ist nicht möglich, weiter als zum Volume zu navigieren.This is significant when calling a method such as Path.GetFullPath(String, String) with relative directory segments; it is never possible to navigate past the volume.

DOS-Gerätepfade sind definitionsgemäß absolut.DOS device paths are fully qualified by definition. Die relativen Verzeichnissegmente (. und ..) sind nicht zulässig.Relative directory segments (. and ..) are not allowed. Aktuelle Verzeichnisse haben bei Verwendung von UNC-Pfaden keine Relevanz.Current directories never enter into their usage.

Beispiel: Möglichkeiten zum Verweisen auf dieselbe DateiExample: Ways to refer to the same file

Im folgenden Beispiel werden einige Möglichkeiten zum Verweisen auf eine Datei veranschaulicht, wenn Sie die APIs des System.IO-Namespace verwenden.The following example illustrates some of the ways in which you can refer to a file when using the APIs in the System.IO namespace. Im Beispiel wird ein FileInfo-Objekt instanziiert und dessen Name- und Length-Eigenschaften verwendet, um den Dateinamen und die Dateigröße anzuzeigen.The example instantiates a FileInfo object and uses its Name and Length properties to display the filename and the length of the file.

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

PfadnormalisierungPath normalization

Die meisten Pfade, die an Windows-APIs übergeben werden, werden normalisiert.Almost all paths passed to Windows APIs are normalized. Während der Normalisierung führt Windows die folgenden Schritte durch:During normalization, Windows performs the following steps:

  • Der Pfad wird identifiziert.Identifies the path.
  • Das aktuelle Verzeichnis wird auf relative Pfade angewandt.Applies the current directory to partially qualified (relative) paths.
  • Komponenten und Verzeichnistrennzeichen werden kanonisiert.Canonicalizes component and directory separators.
  • Relative Verzeichniskomponenten werden ausgewertet (. für das aktuelle Verzeichnis und .. für das übergeordnete Verzeichnis).Evaluates relative directory components (. for the current directory and .. for the parent directory).
  • Bestimmte Zeichen werden gekürzt.Trims certain characters.

Diese Normalisierung erfolgt implizit, Sie können sie jedoch explizit ausführen, indem Sie die Methode Path.GetFullPath aufrufen, die einen Aufruf der GetFullPathName()-Funktion umschließt.This normalization happens implicitly, but you can do it explicitly by calling the Path.GetFullPath method, which wraps a call to the GetFullPathName() function. Sie können die Windows-Funktion GetFullPathName() auch aufrufen, indem Sie „P/Invoke“ verwendenYou can also call the Windows GetFullPathName() function directly using P/Invoke.

Identifizieren des PfadsIdentifying the path

Der erste Schritt der Pfadnormalisierung ist das Identifizieren des Pfadtyps.The first step in path normalization is identifying the type of path. Pfade gehören zu einer von wenigen Kategorien:Paths fall into one of a few categories:

  • Gerätepfade, d.h. sie beginnen mit zwei Trennzeichen und einem Fragezeichen oder einem Punkt (\\? oder \\.).They are device paths; that is, they begin with two separators and a question mark or period (\\? or \\.).
  • UNC-Pfade, d.h. sie beginnen mit zwei Trennzeichen ohne einem Fragezeichen oder Punkt.They are UNC paths; that is, they begin with two separators without a question mark or period.
  • Absolute DOS-Pfade, d.h. sie beginnen mit einem Laufwerkbuchstaben, einem Volumetrennzeichen und einem Komponententrennzeichen (C:\).They are fully qualified DOS paths; that is, they begin with a drive letter, a volume separator, and a component separator (C:\).
  • Sie legen ein Legacygerät fest (CON, LPT1).They designate a legacy device (CON, LPT1).
  • Sie sind relativ zum Stamm des aktuellen Laufwerks, d.h. sie beginnen mit einem einzelnen Komponententrennzeichen (\).They are relative to the root of the current drive; that is, they begin with a single component separator (\).
  • Sie sind relativ zum aktuellen Verzeichnis eines angegebenen Laufwerks, d.h. sie beginnen mit einem Laufwerkbuchstaben, einem Volumetrennzeichen und keinem Komponententrennzeichen (C:).They are relative to the current directory of a specified drive; that is, they begin with a drive letter, a volume separator, and no component separator (C:).
  • Sie sind relativ zum aktuellen Verzeichnis, d.h. sie beginnen mit etwas anderem (temp\testfile.txt).They are relative to the current directory; that is, they begin with anything else (temp\testfile.txt).

Der Typ des Pfad bestimmt, ob ein aktuelles Verzeichnis in irgendeiner Weise angewendet wird.The type of the path determines whether or not a current directory is applied in some way. Er bestimmt auch den „Stamm“ des Pfads.It also determines what the "root" of the path is.

Handhaben von LegacygerätenHandling legacy devices

Wenn der Pfad ein DOS-Legacygerät wie CON, COM1 oder LPT1 ist, wird er durch Voranstellen von \\.\ in einen Gerätepfad konvertiert und zurückgegeben.If the path is a legacy DOS device such as CON, COM1, or LPT1, it is converted into a device path by prepending \\.\ and returned.

Ein Pfad, der mit einem Legacygerätenamen beginnt, wird von der Methode Path.GetFullPath(String) immer als Legacygerät interpretiert.A path that begins with a legacy device name is always interpreted as a legacy device by the Path.GetFullPath(String) method. Beispielsweise ist der DOS-Gerätepfad für CON.TXT \\.\CON, und der DOS-Gerätepfad für COM1.TXT\file1.txt ist \\.\COM1.For example, the DOS device path for CON.TXT is \\.\CON, and the DOS device path for COM1.TXT\file1.txt is \\.\COM1.

Anwenden des aktuellen VerzeichnissesApplying the current directory

Wenn ein Pfad nicht absolut ist, wendet Windows das aktuelle Verzeichnis an.If a path isn't fully qualified, Windows applies the current directory to it. Das aktuelle Verzeichnis wird nicht auf UNC- und Gerätepfade angewendet.UNCs and device paths do not have the current directory applied. Auch nicht auf ein volles Laufwerk mit dem Trennzeichen C:\.Neither does a full drive with separator C:\.

Wenn der Pfad mit einem einzelnen Komponententrennzeichen beginnt, wird das Laufwerk des aktuellen Verzeichnisses angewendet.If the path starts with a single component separator, the drive from the current directory is applied. Wenn der Gerätepfad beispielsweise \utilities entspricht und das aktuelle Verzeichnis C:\temp\ ist, erzeugt die Normalisierung C:\utilities.For example, if the file path is \utilities and the current directory is C:\temp\, normalization produces C:\utilities.

Wenn der Pfad mit einem Laufwerkbuchstaben, einem Volumetrennzeichen und keinem Komponententrennzeichen beginnt, wird das letzte über die Befehlsshell festgelegte aktuelle Verzeichnis für das angegebene Laufwerk angewendet.If the path starts with a drive letter, volume separator, and no component separator, the last current directory set from the command shell for the specified drive is applied. Wenn das letzte aktuelle Verzeichnis nicht festgelegt wurde, wird nur das Laufwerk angewendet.If the last current directory was not set, the drive alone is applied. Wenn der Dateipfad beispielsweise D:sources entspricht, das aktuelle Verzeichnis C:\Documents\ ist, und das letzte aktuelle Verzeichnis auf Laufwerk „D:“ D:\sources\ war, ist das Ergebnis D:\sources\sources.For example, if the file path is D:sources, the current directory is C:\Documents\, and the last current directory on drive D: was D:\sources\, the result is D:\sources\sources. Diese „zum Laufwerk relativen“ Pfade sind eine häufige Ursache für Logikfehler beim Programm und Skript.These "drive relative" paths are a common source of program and script logic errors. Die Annahme, dass ein Pfad, der mit einem Buchstaben und einem Doppelpunkt beginnt, nicht relativ ist, ist offensichtlich falsch.Assuming that a path beginning with a letter and a colon isn't relative is obviously not correct.

Wenn der Pfad mit etwas anderem als einem Trennzeichen beginnt, werden das aktuelle Laufwerk und das aktuelle Verzeichnis angewendet.If the path starts with something other than a separator, the current drive and current directory are applied. Wenn der Pfad beispielsweise filecompare entspricht, und das aktuelle Verzeichnis C:\utilities\ ist, ist das Ergebnis C:\utilities\filecompare\.For example, if the path is filecompare and the current directory is C:\utilities\, the result is C:\utilities\filecompare\.

Wichtig

Relative Pfade sind in Multithreadanwendungen gefährlich (d.h. in den meisten Anwendungen), da das aktuelle Verzeichnis eine prozessspezifische Einstellung ist.Relative paths are dangerous in multithreaded applications (that is, most applications) because the current directory is a per-process setting. Jeder Thread kann das aktuelle Verzeichnis jederzeit ändern.Any thread can change the current directory at any time. Beginnend mit .NET Core 2.1 können Sie die Methode Path.GetFullPath(String, String) aufrufen, um einen absoluten Pfad von einem relativen Pfad und dem Basispfad (dem aktuellen Verzeichnis) abzurufen, gegen die Sie auflösen möchten.Starting with .NET Core 2.1, you can call the Path.GetFullPath(String, String) method to get an absolute path from a relative path and the base path (the current directory) that you want to resolve it against.

Kanonisierende TrennzeichenCanonicalizing separators

Alle führenden Schrägstriche (/) werden in das standardmäßige Trennzeichen von Windows konvertiert, den umgekehrten Schrägstrich (\).All forward slashes (/) are converted into the standard Windows separator, the back slash (\). Wenn sie vorhanden sind, wird eine Reihe von Schrägstrichen, die auf die ersten zwei Schrägstriche folgt, auf einen einzelnen Schrägstrich reduziert.If they are present, a series of slashes that follow the first two slashes are collapsed into a single slash.

Auswerten relativer KomponentenEvaluating relative components

Während der Pfad verarbeitet wird, werden alle Komponenten oder Segmente ausgewertet, die aus einem oder zwei Punkten (. oder ..) bestehen:As the path is processed, any components or segments that are composed of a single or a double period (. or ..) are evaluated:

  • Bei einzelnen Punkten wird das aktuelle Segment entfernt, da es auf das aktuelle Verzeichnis verweist.For a single period, the current segment is removed, since it refers to the current directory.

  • Bei zwei Punkten werden das aktuelle Segment und das übergeordnete Segment entfernt, da die zwei Punkte auf das übergeordnetes Verzeichnis verweisen.For a double period, the current segment and the parent segment are removed, since the double period refers to the parent directory.

    Übergeordnete Verzeichnisse werden nur entfernt, wenn sie sich nicht nach dem Stamm des Pfads befinden.Parent directories are only removed if they aren't past the root of the path. Der Stamm des Pfads ist abhängig von der Art des Pfads.The root of the path depends on the type of path. Für DOS-Pfade ist es das Laufwerk (C:\), für UNC-Pfade ist es „server/share“ (\\Server\Share) und für Gerätepfade ist es das Gerätepfadpräfix (\\?\ oder \\.\).It is the drive (C:\) for DOS paths, the server/share for UNCs (\\Server\Share), and the device path prefix for device paths (\\?\ or \\.\).

Entfernen von ZeichenTrimming characters

Zusätzlich zu den Ausführungen von Trennzeichen und Segmenten, die weiter oben entfernt wurden, werden einige zusätzliche Zeichen während der Normalisierung entfernt:Along with the runs of separators and relative segments removed earlier, some additional characters are removed during normalization:

  • Wenn ein Segment mit einem einzelnen Punkt endet, wird der Punkt entfernt.If a segment ends in a single period, that period is removed. (Im vorherigen Schritt wurde ein Segment aus einem oder zwei Punkten normalisiert.(A segment of a single or double period is normalized in the previous step. Ein Segment aus mindestens drei Punkten wird nicht normalisiert. Tatsächlich ist das ein gültiger Datei- oder Verzeichnisname.)A segment of three or more periods is not normalized and is actually a valid file/directory name.)

  • Wenn der Pfad nicht mit einem Trennzeichen endet, werden alle nachfolgenden Punkte und Leerzeichen (U+0020) entfernt.If the path doesn't end in a separator, all trailing periods and spaces (U+0020) are removed. Wenn das letzte Segment nur aus einem oder zwei Punkten besteht, unterliegt es den oben genannten Regeln für relative Komponenten.If the last segment is simply a single or double period, it falls under the relative components rule above.

    Diese Regel bedeutet, dass Sie einen Verzeichnisnamen mit einem nachfolgendem Leerzeichen erstellen können, indem Sie nach dem Leerzeichen ein Trennzeichen hinzufügen.This rule means that you can create a directory name with a trailing space by adding a trailing separator after the space.

    Wichtig

    Sie sollten nie Verzeichnisse oder Dateinamen mit nachstehenden Leerzeichen erstellen.You should never create a directory or filename with a trailing space. Nachstehende Leerzeichen machen es schwer, wenn nicht sogar unmöglich, auf ein Verzeichnis zuzugreifen. Außerdem treten häufig Fehler auf, wenn Anwendungen versuchen, Verzeichnisse oder Dateien zu verarbeiten, deren Namen nachstehende Leerzeichen enthalten.Trailing spaces can make it difficult or impossible to access a directory, and applications commonly fail when attempting to handle directories or files whose names include trailing spaces.

Überspringen der NormalisierungSkipping normalization

Normalerweise werden alle Pfade, die an die Windows-API übergeben werden, effektiv an die GetFullPathName-Funktion übergeben und normalisiert.Normally, any path passed to a Windows API is (effectively) passed to the GetFullPathName function and normalized. Es gibt eine wichtige Ausnahme: ein Gerätepfad, der mit einem Fragezeichen statt einem Punkt beginnt.There is one important exception: a device path that begins with a question mark instead of a period. Sofern der Pfad nicht mit \\?\ beginnt (beachten Sie die Verwendung des kanonischen umgekehrten Schrägstrichs), ist er normalisiert.Unless the path starts exactly with \\?\ (note the use of the canonical backslash), it is normalized.

Warum kann es sinnvoll sein, die Normalisierung zu überspringen?Why would you want to skip normalization? Es gibt drei wichtige Gründe:There are three major reasons:

  1. Um Zugriff auf Pfade zu erhalten, die zwar zulässig sind, aber normalerweise nicht verfügbar.To get access to paths that are normally unavailable but are legal. Beispielsweise ist es auf keine andere Weise möglich, Zugriff auf eine Datei oder ein Verzeichnis namens hidden. zu erhalten.A file or directory called hidden., for example, is impossible to access in any other way.

  2. Zur Verbesserung der Leistung, wenn Sie die Normalisierung bereits durchgeführt haben.To improve performance by skipping normalization if you've already normalized.

  3. Zum Überspringen der MAX_PATH-Überprüfung der Pfadlänge, um Pfade zu ermöglichen, die länger als 259 Zeichen sind (nur in .NET Framework).On the .NET Framework only, to skip the MAX_PATH check for path length to allow for paths that are greater than 259 characters. Abgesehen von einigen Ausnahmen ist dies mit den meisten APIs möglich.Most APIs allow this, with some exceptions.

Hinweis

.NET Core verarbeitet lange Pfade implizit und führt keine MAX_PATH-Überprüfung durch..NET Core handles long paths implicitly and does not perform a MAX_PATH check. Die MAX_PATH-Überprüfung gilt nur für .NET Framework.The MAX_PATH check applies only to the .NET Framework.

Das Überspringen der Normalisierung und MAX_PATH-Überprüfungen ist der einzige Unterschied zwischen den zwei Gerätepfadsyntaxen. Andernfalls sind sie identisch.Skipping normalization and max path checks is the only difference between the two device path syntaxes; they are otherwise identical. Beachten Sie, dass Sie durch Überspringen der Normalisierung Pfade erstellen können, die für „normale“ Anwendungen schwer zu verarbeiten sind.Be careful with skipping normalization, since you can easily create paths that are difficult for "normal" applications to deal with.

Pfade, die mit \\?\ beginnen, werden weiterhin normalisiert, wenn Sie sie explizit an die GetFullPathName-Funktion übergeben.Paths that start with \\?\ are still normalized if you explicitly pass them to the GetFullPathName function.

Beachten Sie, dass Sie Pfade mit mehr Zeichen als MAX_PATH verwenden können, um GetFullPathName ohne \\?\ abzurufen.Note that you can paths of more than MAX_PATH characters to GetFullPathName without \\?\. Beliebige Pfadlängen werden bis zur maximalen Länge von Zeichenfolgen unterstützt, die Windows verarbeiten kann.It supports arbitrary length paths up to the maximum string size that Windows can handle.

Groß-/Kleinbuchstaben im Windows-DateisystemCase and the Windows file system

Dass Pfad- und Verzeichnisnamen die Groß-/Kleinschreibung ignorieren, ist eine Besonderheit vom Windows-Dateisystem, was viele Benutzer und Entwickler verwirrt, die Windows nicht verwenden.A peculiarity of the Windows file system that non-Windows users and developers find confusing is that path and directory names are case-insensitive. Das bedeutet, dass Verzeichnis- und Dateinamen die Schreibweise der Zeichenfolgen darstellen, mit der sie erstellt wurden.That is, directory and file names reflect the casing of the strings used when they are created. Zum Beispiel erstellt der MethodenaufrufFor example, the method call

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

ein Verzeichnis namens TeStDiReCtOrY.creates a directory named TeStDiReCtOrY. Wenn Sie ein Verzeichnis oder eine Datei umbenennen, um die Groß-/Kleinschreibung zu ändern, wird die entsprechende Zeichenfolge angezeigt, die Sie beim Umbenennen eingegeben haben.If you rename a directory or file to change its case, the directory or file name reflects the case of the string used when you rename it. Der folgende Code benennt beispielweise eine Datei namens „test.txt“ in „Test.txt“ um:For example, the following code renames a file named test.txt to 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

Allerdings berücksichtigen Vergleiche von Verzeichnis- und Dateinamen die Groß-/Kleinschreibung nicht.However, directory and file name comparisons are case-insensitive. Wenn Sie nach einer Datei namens „test.txt“ suchen, ignorieren .NET-Dateisystem-APIs die Groß-/Kleinschreibung für Vergleiche.If you search for a file named "test.txt", .NET file system APIs ignore case in the comparison. „Test.txt“, „TEST.TXT“, „test.TXT“ und beliebige andere Kombinationen aus Groß- und Kleinbuchstaben entsprechen „test.txt“.Test.txt, TEST.TXT, test.TXT, and any other combination of upper- and lowercase letters will match "test.txt".