Formats de chemin de fichier sur les systèmes WindowsFile path formats on Windows systems

Dans l’espace de noms System.IO, les membres de nombreux types incluent un paramètre path qui vous permet de spécifier un chemin absolu ou relatif à une ressource de système de fichiers.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. Ce chemin est ensuite passé aux API de système de fichiers Windows.This path is then passed to Windows file system APIs. Cette rubrique décrit les formats de chemins de fichier que vous pouvez utiliser dans les systèmes Windows.This topic discusses the formats for file paths that you can use on Windows systems.

Chemins DOS traditionnelsTraditional DOS paths

Un chemin DOS standard peut être constitué de trois composants :A standard DOS path can consist of three components:

Si les trois composants sont présents, le chemin est absolu.If all three components are present, the path is absolute. Si aucune lettre de lecteur ou de volume n’est spécifiée et que le caractère de séparation de répertoires précède les noms de répertoires, le chemin est relatif à la racine du lecteur actif.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. Sinon, le chemin est relatif au répertoire actif.Otherwise, the path is relative to the current directory. Le tableau suivant présente certains chemins de répertoire et de fichier.The following table shows some possible directory and file paths.

Chemin d’accèsPath DescriptionDescription
C:\Documents\Newsletters\Summer2018.pdf Chemin de fichier absolu à partir de la racine du lecteur C:.An absolute file path from the root of drive C:
\Program Files\Custom Utilities\StringFinder.exe Chemin absolu à partir de la racine du lecteur actif.An absolute path from the root of the current drive.
2018\January.xlsx Chemin relatif à un fichier dans un sous-répertoire du répertoire actif.A relative path to a file in a subdirectory of the current directory.
..\Publications\TravelBrochure.pdf Chemin relatif à un fichier dans répertoire qui est un pair du répertoire actif.A relative path to file in a directory that is a peer of the current directory.
C:\Projects\apilibrary\apilibrary.sln Chemin absolu à un fichier à partir de la racine du lecteur C:.An absolute path to a file from the root of drive C:
C:Projects\apilibrary\apilibrary.sln Chemin relatif à partir du répertoire actif du lecteur C:.A relative path from the current directory of the C: drive.

Important

Notez la différence entre les deux derniers chemins.Note the difference between the last two paths. Les deux chemins spécifient le spécificateur de volume facultatif (C: dans les deux cas), mais le premier commence par la racine du volume spécifié, contrairement au second.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. Le premier chemin est donc un chemin absolu à partir du répertoire racine du lecteur C:, tandis que le second est un chemin relatif à partir du répertoire actif du lecteur C:.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:. L’utilisation involontaire de la deuxième forme à la place de la première est une source courante de bogues impliquant des chemins de fichier Windows.Use of the second form when the first is intended is a common source of bugs that involve Windows file paths.

Pour déterminer si un chemin de fichier est complet (autrement dit, si le chemin est indépendant du répertoire actif et qu’il reste inchangé quand le répertoire actif change), appelez la méthode IsPathFullyQualified.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. Notez qu’un tel chemin peut inclure des segments de répertoire relatifs (. et ..) et toujours être complet si le chemin résolu pointe toujours vers le même emplacement.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.

L’exemple suivant illustre la différence entre les chemins absolus et relatifs.The following example illustrates the difference between absolute and relative paths. Il suppose que le répertoire D:\FY2018\ existe et que vous n’avez défini aucun répertoire actif pour D:\ à l’invite de commandes avant d’exécuter l’exemple.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

Chemins UNCUNC paths

Les chemins respectant la convention d’affectation de noms (UNC), qui sont utilisés pour accéder aux ressources réseau, ont le format suivant :Universal naming convention (UNC) paths, which are used to access network resources, have the following format:

  • Un nom de serveur ou d’hôte, précédé de \\.A server or host name, which is prefaced by \\. Le nom du serveur peut être un nom d’ordinateur NetBIOS ou une adresse IP/FQDN (IPv4 et IPv6 sont pris en charge).The server name can be a NetBIOS machine name or an IP/FQDN address (IPv4 as well as v6 are supported).
  • Un nom de partage, séparé du nom d’hôte par \.A share name, which is separated from the host name by \. Ensemble, le serveur et le partage forment le volume.Together, the server and share name make up the volume.
  • Un nom de répertoire.A directory name. Le caractère de séparation de répertoires sépare les sous-répertoires au sein de la hiérarchie de répertoires imbriqués.The directory separator character separates subdirectories within the nested directory hierarchy.
  • Un nom de fichier facultatif.An optional filename. Le caractère de séparation de répertoires sépare le chemin et le nom de fichier.The directory separator character separates the file path and the filename.

Voici quelques exemples de chemins UNC :The following are some examples of UNC paths:

Chemin d’accèsPath DescriptionDescription
\\system07\C$\ Répertoire racine du lecteur C: sur system07.The root directory of the C: drive on system07.
\\Server2\Share\Test\Foo.txt Fichier Foo.txt dans le répertoire Test du volume \\Server2\Share.The Foo.txt file in the Test directory of the \\Server2\Share volume.

Les chemins UNC doivent toujours être complets.UNC paths must always be fully qualified. Ils peuvent inclure des segments de répertoire relatifs (. et ..), mais il doivent faire partie d’un chemin complet.They can include relative directory segments (. and ..), but these must be part of a fully qualified path. Pour utiliser des chemins relatifs, vous devez impérativement mapper un chemin UNC à une lettre de lecteur.You can use relative paths only by mapping a UNC path to a drive letter.

Chemins de périphérique DOSDOS device paths

Le système d’exploitation Windows a un modèle objet unifié qui pointe vers toutes les ressources, notamment les fichiers.The Windows operating system has a unified object model that points to all resources, including files. Ces chemins d’objet sont accessibles à partir de la fenêtre de console et sont exposés à la couche Win32 par le biais d’un dossier spécial de liens symboliques mappés aux chemins DOS et UNC hérités.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. Ce dossier spécial est accessible par le biais d’un chemin de périphérique DOS, dont la syntaxe est l’une des suivantes :This special folder is accessed via the DOS device path syntax, which is one of:

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

En plus d’identifier un lecteur par sa lettre de lecteur, vous pouvez identifier un volume à l’aide de son GUID de volume.In addition to identifying a drive by its drive letter, you can identify a volume by using its volume GUID. Cela prend la forme :This takes the form:

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

Notes

La syntaxe des chemins de périphérique DOS est prise en charge sur les implémentations .NET s’exécutant sur Windows à compter de .NET Core 1.1 et .NET Framework 4.6.2.DOS device path syntax is supported on .NET implementations running on Windows starting with .NET Core 1.1 and .NET Framework 4.6.2.

Le chemin de périphérique DOS comprend les composants suivants :The DOS device path consists of the following components:

  • Le spécificateur de chemin de périphérique (\\.\ ou \\?\), qui identifie le chemin comme chemin de périphérique DOS.The device path specifier (\\.\ or \\?\), which identifies the path as a DOS device path.

    Notes

    Le spécificateur \\?\ est pris en charge dans toutes les versions de .NET Core et dans le .NET Framework à compter de la version 4.6.2.The \\?\ is supported in all versions of .NET Core and in the .NET Framework starting with version 4.6.2.

  • Un lien symbolique vers le « vrai » objet d’appareil (C: dans le cas d’un nom de lecteur, ou Volume{b75e2c83-0000-0000-0000-602f00000000} dans le cas d’un GUID de volume).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).

    Le premier segment du chemin de périphérique DOS après le spécificateur de chemin de périphérique identifie le volume ou le lecteur.The first segment of the DOS device path after the device path specifier identifies the volume or drive. (Par exemple, \\?\C:\ et \\.\BootPartition\.)(For example, \\?\C:\ and \\.\BootPartition\.)

    Il existe un lien spécifique pour les chemins UNC. Celui-ci s’appelle, sans surprise, UNC.There is a specific link for UNCs that is called, not surprisingly, UNC. Par exemple :For example:

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

    Pour les chemins UNC de périphérique, la partie serveur/partage forme le volume.For device UNCs, the server/share portion forms the volume. Par exemple, dans \\?\server1\e:\utilities\\filecomparer\, la partie serveur/partage est server1\utilities.For example, in \\?\server1\e:\utilities\\filecomparer\, the server/share portion is server1\utilities. Ceci est important quand vous appelez une méthode comme Path.GetFullPath(String, String) avec des segments de répertoire relatifs ; il est impossible de naviguer au-delà du volume.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.

Par définition, les chemins de périphérique DOS sont complets.DOS device paths are fully qualified by definition. Les segments de répertoire relatifs (. et ..) ne sont pas autorisés.Relative directory segments (. and ..) are not allowed. Les répertoires actifs ne font jamais partie de ce type de chemin.Current directories never enter into their usage.

Exemple : Comment faire référence au même fichierExample: Ways to refer to the same file

L’exemple suivant illustre quelques-unes des méthodes vous permettant de faire référence à un fichier à l’aide des API dans l’espace de noms System.IO.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. L’exemple instancie un objet FileInfo et utilise ses propriétés Name et Length pour afficher le nom et la longueur du fichier.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

Normalisation des chemins d’accèsPath normalization

Presque tous les chemins passés aux API Windows sont normalisés.Almost all paths passed to Windows APIs are normalized. Durant la normalisation, Windows effectue les étapes suivantes :During normalization, Windows performs the following steps:

  • Identifie le chemin.Identifies the path.
  • Applique le répertoire actif aux chemins partiels (relatifs).Applies the current directory to partially qualified (relative) paths.
  • Applique une mise en forme canonique aux séparateurs de composants et de répertoires.Canonicalizes component and directory separators.
  • Évalue les composants des répertoires relatifs (. pour le répertoire actif et .. pour le répertoire parent).Evaluates relative directory components (. for the current directory and .. for the parent directory).
  • Supprime certains caractères.Trims certain characters.

Cette normalisation se produit implicitement, mais vous pouvez l’effectuer explicitement en appelant la méthode Path.GetFullPath, qui inclut dans un wrapper un appel à la fonction GetFullPathName().This normalization happens implicitly, but you can do it explicitly by calling the Path.GetFullPath method, which wraps a call to the GetFullPathName() function. Vous pouvez également appeler directement la fonction GetFullPathName() Windows à l’aide de P/Invoke.You can also call the Windows GetFullPathName() function directly using P/Invoke.

Identification du cheminIdentifying the path

La première étape de normalisation d’un chemin consiste à identifier le type du chemin.The first step in path normalization is identifying the type of path. Les chemins appartiennent à l’une des catégories suivantes :Paths fall into one of a few categories:

  • Chemins de périphérique : commencent par deux séparateurs et un point d’interrogation ou un point (\\? ou \\.).They are device paths; that is, they begin with two separators and a question mark or period (\\? or \\.).
  • Chemins UNC : commencent par deux séparateurs sans point d’interrogation ou point.They are UNC paths; that is, they begin with two separators without a question mark or period.
  • Chemins DOS complets : commencent par une lettre de lecteur, un séparateur de volumes et un séparateur de composants (C:\).They are fully qualified DOS paths; that is, they begin with a drive letter, a volume separator, and a component separator (C:\).
  • Chemins désignant un périphérique hérité (CON, LPT1).They designate a legacy device (CON, LPT1).
  • Chemins relatifs à la racine du lecteur actif : commencent par un séparateur de composants unique (\).They are relative to the root of the current drive; that is, they begin with a single component separator (\).
  • Chemins relatifs au répertoire actif d’un lecteur spécifié : commencent par une lettre de lecteur, un séparateur de volumes et aucun séparateur de composants (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:).
  • Chemins relatifs au répertoire actif : ils commencent par autre chose (temp\testfile.txt).They are relative to the current directory; that is, they begin with anything else (temp\testfile.txt).

Le type du chemin détermine si un répertoire actif est appliqué ou non d’une certaine façon.The type of the path determines whether or not a current directory is applied in some way. Il détermine également la « racine » du chemin.It also determines what the "root" of the path is.

Gestion des périphériques héritésHandling legacy devices

Si le chemin est un périphérique DOS hérité comme CON, COM1 ou LPT1, il est converti en chemin de périphérique (préfixe \\.\ ajouté) et retourné.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.

Un chemin qui commence par un nom de périphérique hérité est toujours interprété comme périphérique hérité par la méthode Path.GetFullPath(String).A path that begins with a legacy device name is always interpreted as a legacy device by the Path.GetFullPath(String) method. Par exemple, le chemin de périphérique DOS pour CON.TXT est \\.\CON, et celui pour COM1.TXT\file1.txt est \\.\COM1.For example, the DOS device path for CON.TXT is \\.\CON, and the DOS device path for COM1.TXT\file1.txt is \\.\COM1.

Application du répertoire actifApplying the current directory

Si un chemin n’est pas complet, Windows applique à celui-ci le répertoire actif.If a path isn't fully qualified, Windows applies the current directory to it. Le répertoire actif n’est pas appliqué aux chemins UNC et de périphérique.UNCs and device paths do not have the current directory applied. Il n’est pas non plus appliqué à un lecteur complet avec le séparateur C:\.Neither does a full drive with separator C:\.

Si le chemin commence par un séparateur de composant unique, le lecteur du répertoire actif est appliqué.If the path starts with a single component separator, the drive from the current directory is applied. Par exemple, si le chemin de fichier est \utilities et le répertoire actif C:\temp\, la normalisation produit C:\utilities.For example, if the file path is \utilities and the current directory is C:\temp\, normalization produces C:\utilities.

Si le chemin commence par une lettre de lecteur, comprend un séparateur de volumes, mais ne contient aucun séparateur de composants, le dernier répertoire actif défini à partir de l’interface de commande pour le lecteur spécifié est appliqué.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. Si le dernier répertoire actif n’a pas été défini, seul le lecteur est appliqué.If the last current directory was not set, the drive alone is applied. Par exemple, si le chemin de fichier est D:sources, le répertoire actif C:\Documents\ et le dernier répertoire actif sur le lecteur D: D:\sources\, le résultat est 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. Ces chemins « relatifs au lecteur » sont une source commune d’erreurs de logique qui affectent les programmes et les scripts.These "drive relative" paths are a common source of program and script logic errors. Il est évidemment incorrect d’assumer qu’un chemin commençant par une lettre et un signe deux-points n’est pas relatif.Assuming that a path beginning with a letter and a colon isn't relative is obviously not correct.

Si le chemin commence par un élément autre qu’un séparateur, le lecteur et le répertoire actifs sont appliqués.If the path starts with something other than a separator, the current drive and current directory are applied. Par exemple, si le chemin est filecompare et le répertoire actif C:\utilities\, le résultat est C:\utilities\filecompare\.For example, if the path is filecompare and the current directory is C:\utilities\, the result is C:\utilities\filecompare\.

Important

Les chemins relatifs sont dangereux dans les applications multithreads (c’est-à-dire dans la plupart des applications), car le répertoire actif est un paramètre par processus.Relative paths are dangerous in multithreaded applications (that is, most applications) because the current directory is a per-process setting. N’importe quel thread peut changer le répertoire actif à tout moment.Any thread can change the current directory at any time. À compter de .NET Core 2.1, vous pouvez appeler la méthode Path.GetFullPath(String, String) pour obtenir un chemin absolu à partir d’un chemin relatif et le chemin de base (répertoire actif) par rapport auquel vous souhaitez le résoudre.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.

Mise en forme canonique des séparateursCanonicalizing separators

Toute barre oblique (/) est convertie en séparateur Windows standard, à savoir la barre oblique inverse (\).All forward slashes (/) are converted into the standard Windows separator, the back slash (\). Toute série de barres obliques après les deux premières barres obliques est réduite en barre oblique unique.If they are present, a series of slashes that follow the first two slashes are collapsed into a single slash.

Évaluation des composants relatifsEvaluating relative components

À mesure que le chemin est traité, tout composant ou segment constitué d’un point unique ou double (. ou ..) est évalué :As the path is processed, any components or segments that are composed of a single or a double period (. or ..) are evaluated:

  • Pour un point unique, le segment actif est supprimé, car il fait référence au répertoire actif.For a single period, the current segment is removed, since it refers to the current directory.

  • Pour un point double, le segment actif et le segment parent sont supprimés, car il fait référence au répertoire parent.For a double period, the current segment and the parent segment are removed, since the double period refers to the parent directory.

    Les répertoires parents sont uniquement supprimés s’ils ne sont pas situés au-delà de la racine du chemin.Parent directories are only removed if they aren't past the root of the path. La racine du chemin varie selon le type de chemin.The root of the path depends on the type of path. Il s’agit du lecteur (C:\) pour les chemins DOS, du serveur/partage pour les chemins UNC (\\Server\Share) et du préfixe du chemin de périphérique pour les chemins de périphérique (\\?\ ou \\.\).It is the drive (C:\) for DOS paths, the server/share for UNCs (\\Server\Share), and the device path prefix for device paths (\\?\ or \\.\).

Suppression de caractèresTrimming characters

Outre les séries de séparateurs et de segments relatifs supprimés précédemment, d’autres caractères sont supprimés durant la normalisation :Along with the runs of separators and relative segments removed earlier, some additional characters are removed during normalization:

  • Si un segment se termine par un point unique, celui-ci est supprimé.If a segment ends in a single period, that period is removed. (Un segment constitué d’un point unique ou double est normalisé à l’étape précédente.(A segment of a single or double period is normalized in the previous step. Un segment constitué de trois ou quatre points n’est pas normalisé, car il s’agit d’un nom de fichier/répertoire valide.)A segment of three or more periods is not normalized and is actually a valid file/directory name.)

  • Si le chemin ne se termine pas par un séparateur, tous les points et espaces (U+0020) de fin sont supprimés.If the path doesn't end in a separator, all trailing periods and spaces (U+0020) are removed. Si le dernier segment est simplement un point simple ou double, il relève de la règle des composants relatifs ci-dessus.If the last segment is simply a single or double period, it falls under the relative components rule above.

    Cette règle signifie que vous pouvez créer un nom de répertoire avec un espace de fin en ajoutant un séparateur de fin après l’espace.This rule means that you can create a directory name with a trailing space by adding a trailing separator after the space.

    Important

    Ne créez jamais un répertoire ou un nom de fichier avec un espace de fin.You should never create a directory or filename with a trailing space. Les espaces de fin peuvent rendre l’accès à un répertoire difficile voire impossible, et il arrive fréquemment que des applications échouent quand vous tentez de gérer des répertoires ou des fichiers dont les noms comprennent des espaces de fin.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.

Ignorer la normalisationSkipping normalization

En règle générale, tout chemin passé à une API Windows est (effectivement) passé à la fonction GetFullPathName et normalisé.Normally, any path passed to a Windows API is (effectively) passed to the GetFullPathName function and normalized. Il existe toutefois une exception importante : un chemin de périphérique qui commence par un point d’interrogation et non un point.There is one important exception: a device path that begins with a question mark instead of a period. À moins qu’il ne commence exactement par \\?\ (notez l’utilisation de la barre oblique inverse canonique), le chemin est normalisé.Unless the path starts exactly with \\?\ (note the use of the canonical backslash), it is normalized.

Pourquoi ignorer la normalisation ?Why would you want to skip normalization? Voici les trois raisons principales :There are three major reasons:

  1. Accéder aux chemins normalement indisponibles, mais autorisés.To get access to paths that are normally unavailable but are legal. Par exemple, il est impossible d’accéder à un fichier ou à un répertoire appelé hidden. d’une autre manière.A file or directory called hidden., for example, is impossible to access in any other way.

  2. Améliorer le niveau de performance en ignorant la normalisation précédemment effectuée.To improve performance by skipping normalization if you've already normalized.

  3. Sur le .NET Framework uniquement, ignorer la vérification de la longueur du chemin (MAX_PATH) et autoriser les chemins de plus de 259 caractères.On the .NET Framework only, to skip the MAX_PATH check for path length to allow for paths that are greater than 259 characters. La plupart des API autorisent ceci, à quelques exceptions près.Most APIs allow this, with some exceptions.

Notes

.NET Core gère implicitement les chemins longs et n’effectue pas la vérification MAX_PATH..NET Core handles long paths implicitly and does not perform a MAX_PATH check. La vérification MAX_PATH s’applique uniquement au .NET Framework.The MAX_PATH check applies only to the .NET Framework.

La seule différence entre les deux syntaxes de chemin de périphérique tient au fait que vous pouvez ignorer la normalisation et les vérifications de la longueur maximale des chemins ; sinon, elles sont identiques.Skipping normalization and max path checks is the only difference between the two device path syntaxes; they are otherwise identical. Soyez prudent si vous choisissez d’ignorer la normalisation, car vous pouvez facilement créer des chemins difficiles à gérer pour les applications « normales ».Be careful with skipping normalization, since you can easily create paths that are difficult for "normal" applications to deal with.

Les chemins qui commencent par \\?\ sont toujours normalisés si vous les passez explicitement à la fonction GetFullPathName.Paths that start with \\?\ are still normalized if you explicitly pass them to the GetFullPathName function.

Notez que vous pouvez passer les chemins de plus de MAX_PATH caractères à la fonction GetFullPathName sans \\?\.Note that you can paths of more than MAX_PATH characters to GetFullPathName without \\?\. Elle prend en charge les chemins de longueur arbitraire jusqu’à la taille de chaîne maximale gérée par Windows.It supports arbitrary length paths up to the maximum string size that Windows can handle.

Casse et système de fichiers WindowsCase and the Windows file system

Le fait que les noms de chemin et de répertoire ne respectent pas la casse est une particularité du système de fichiers Windows que les développeurs et utilisateurs d’autres systèmes d’exploitation trouvent déroutante.A peculiarity of the Windows file system that non-Windows users and developers find confusing is that path and directory names are case-insensitive. Autrement dit, les noms de répertoire et de fichier reflètent la casse des chaînes utilisée au moment de leur création.That is, directory and file names reflect the casing of the strings used when they are created. Par exemple, l’appel de méthodeFor example, the method call

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

crée un répertoire nommé TeStDiReCtOrY.creates a directory named TeStDiReCtOrY. Si vous renommez un répertoire ou un fichier pour changer sa casse, le nom du répertoire ou du fichier reflète la casse de la chaîne utilisée au moment du renommage.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. Par exemple, le code suivant renomme un fichier nommé test.txt en Test.txt :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

Toutefois, les comparaisons des noms de répertoire et de fichier ne respectent pas la casse.However, directory and file name comparisons are case-insensitive. Si vous recherchez un fichier nommé « test.txt », les API du système de fichiers .NET ignorent la casse dans la comparaison.If you search for a file named "test.txt", .NET file system APIs ignore case in the comparison. Test.txt, TEST.TXT, test.TXT et toute autre combinaison de lettres majuscules et minuscules équivalent à « test.txt ».Test.txt, TEST.TXT, test.TXT, and any other combination of upper- and lowercase letters will match "test.txt".