Bienvenue à Blogs CodeS-SourceS Identification | Inscription | Aide

CoqBlog

.NET is good :-)
{ Blog de Gaël Covain }

Actualités

Path.Combine : "Rep1\Rep2\File.ext" != "\Rep1\Rep2\File.ext"

Certains s'étonnent devant le retour de la méthode Path.Combine pour le code suivant :

String path1 = @"C:\Rep0";
String path2 = @"\Rep1\Rep2\File.ext";
String path = Path.Combine(path1, path2);

En effet, path contiendra "\Rep1\Rep2\File.ext" alors que certains s'attendent à avoir "C:\Rep0\Rep1\Rep2\File.ext".

Pourquoi alors qu'on nous répète si souvent qu'un des avantages d'utiliser Path.Combine est de s'affranchir de la vérification manuelle de l'existence ou non d'un \ en fin de chemin de répertoire, les codes suivants ne retournent pas tous la même chose : "C:\Rep0\Rep1\Rep2\File.ext" ?

String path1;
String path2;
String path;

path1 = @"C:\Rep0";
path2 = @"\Rep1\Rep2\File.ext";
path = Path.Combine(path1, path2); // \Rep1\Rep2\File.ext

path1 = @"C:\Rep0";
path2 = @"Rep1\Rep2\File.ext";
path = Path.Combine(path1, path2); // C:\Rep0\Rep1\Rep2\File.ext

path1 = @"C:\Rep0\";
path2 = @"\Rep1\Rep2\File.ext";
path = Path.Combine(path1, path2); // \Rep1\Rep2\File.ext

path1 = @"C:\Rep0\";
path2 = @"Rep1\Rep2\File.ext";
path = Path.Combine(path1, path2); // C:\Rep0\Rep1\Rep2\File.ext

 

Ce comportement est conforme à ce qui est annoncé dans la documentation de Path.Combine :

"[...]Si path2 inclut une racine, path2 est retourné.[...]" / "[...]If path2 includes a root, path2 is returned.[...]"

 

Donc "\Rep1\Rep2\File.ext" est considéré comme possédant une racine ? Il s'agit donc d'un chemin absolu ?
Personnellement je le considère plutôt comme étant à mi chemin entre le chemin relatif et le chemin absolu : là où "Rep1\Rep2\File.ext" est relatif au répertoire courant, "\Rep1\Rep2\File.ext" est en fait relatif à la racine du répertoire courant.
Même si on ne l'est que de la racine, on reste dépendant du répertoire courant.

Exemple, si le répertoire courant est "C:\Rep0", le chemin complet (voir Path.GetFullPath ou directement GetFullPathName / GetFullPathNameTransacted) de

  • "Rep1\Rep2\File.ext" est "C:\Rep0\Rep1\Rep2\File.ext"
  • "\Rep1\Rep2\File.ext" est "C:\Rep1\Rep2\File.ext"

Mais dans les faits, il ne s'agit pas d'un chemin relatif, comme le spécifie la section "Relative Paths" de cette page de la documentation :

"[...]A file name is relative to the current directory if it does not begin with one of the following:

  • A drive name, which is either a drive letter followed by a colon, or a UNC name.
  • A directory name separator (backslash), for example, \subdirectory).

[...]"

 

Ce type de chemin est d'ailleurs tout à fait utilisable directement avec SetCurrentDirectory, et la documentation de GetCurrentDirectory aborde elle aussi le sujet :

"In certain rare cases, if the specified directory is on the current drive, the function might omit the drive letter and colon from the path. Therefore, the size that is returned by the function might be two characters less than the size of the specified string, not including the terminating null character. This behavior might occur in edge situations such as in a services application. If you need the drive letter, make a subsequent call to GetFullPathName to retrieve the drive letter."

Au passage si quelqu'un sait comment reproduire ce comportement sur GetCurrentDirectory, je prends.

 

Vous l'utilisez aussi probablement dans cmd ou PowerShell si vous voulez positionner le répertoire courant à la racine : vous tapez "cd \", pas "cd C:\".

 

Bref, je résume : "Rep1\Rep2\File.ext" != "\Rep1\Rep2\File.ext"

 

Naming a File (Windows)
Path.Combine Method (System.IO)
Path.GetFullPath Method (System.IO)
GetFullPathName Function (Windows) / GetFullPathNameTransacted Function (Windows)
GetCurrentDirectory Function (Windows)
SetCurrentDirectory Function (Windows)

Ce post vous a plu ? Ajoutez le dans vos favoris pour ne pas perdre de temps à le retrouver le jour où vous en aurez besoin :
Posted: lundi 24 mars 2008 14:40 par coq
Classé sous : , ,

Commentaires

brunews a dit :

En C directement:

char buf[264];

PathCombine(buf, szPthA, szPthB);

MessageBox(0, buf, szappname, 0);

POUR:

szPthA : "C:\Rep0";

szPthB[] : "\Rep1\Rep2\File.ext";

ON OBTIENT: C:\Rep1\Rep2\File.ext

POUR:

szPthA : "C:\Rep0";

szPthB[] : "Rep1\Rep2\File.ext";

ON OBTIENT: C:\Rep0\Rep1\Rep2\File.ext

Le 1er exemple ne donne pas le même résultat que .NET, il ne faut donc pas chercher l'explication d'un résultat .NET dans la doc API du système.

A noter aussi que le répertoire courant n'entre vraiment pour rien dans l'affaire.

PathCombine() fait partie de ces fonctions inutiles et donc nuisibles qu'il convient d'éviter.

# mars 24, 2008 19:41

mdislaire a dit :

Mince alors, va falloir que je vérifie ça maintenant. C'est malin...

Sinon tu peux regarder cette classe : https://svn.berlios.de/wsvn/serverlight/trunk/src/PathHelper.cs

Elle va peut être t'intéresser.

# mars 28, 2008 00:30

coq a dit :

Yep, si ça te tente tu peux aussi jeter un oeil au projet FileDirectoryPath de Patrick Smacchia : http://www.codeplex.com/FileDirectoryPath

# mars 29, 2008 12:25
Les commentaires anonymes sont désactivés

Les 10 derniers blogs postés

- Rosario - Team Foundation Server - MSBuild + Workflow Foundation par Azra [Florent Santin] le il y a 6 heures et 53 minutes

- [Fun] : J'en ai toujours rêvé, mais il y en a UN qui l'a fait !!! par The Mit's Blog le il y a 8 heures et 3 minutes

- Par cette chaleur, offrez-vous un hamac branché ! par RedoBlog - The .NET Gentleman !!! le il y a 9 heures et 28 minutes

- ZUNE : Comment récupérer le menu "MarketPlace" dans le ZUNE SoftWare par Blog Technique de Romelard Fabrice le il y a 11 heures et 31 minutes

- ZUNE : Nouvelle version (2.5) de ZUNE Software et ZUNE Device par Blog Technique de Romelard Fabrice le il y a 14 heures et 58 minutes

- [Belgium] : Community Day 2008... 26 Juin 2008. par RedoBlog - The .NET Gentleman !!! le 05-08-2008, 15:59

- Crypter ses données en toute simplicité par Julien Chable le 05-08-2008, 10:24

- XNA : La 3.0 CTP disponible, développez sur Zune et bien d'autres nouveautés... par Blog technique de Nicolas Boonaert le 05-07-2008, 23:47

- SharePoint : Bug sur l'envoi de mail dans les WorkFlow par Blog Technique de Romelard Fabrice le 05-07-2008, 21:35

- Advanced Data Migration Map Editor et Jeu de données exemples pour MSCRM 4.0 par Clark, C#, MSCRM, SBS le 05-07-2008, 16:12