200 votes

Comment obtenir le chemin relatif du chemin absolu

Il y a une partie de mes applications qui affichent le chemin d'accès du fichier chargé par l'utilisateur à travers OpenFileDialog. C'est prendre trop de place pour afficher le chemin d'accès complet, mais je ne veux pas afficher uniquement le nom de fichier comme il peut être ambiguë. Donc, je préfère montrer le chemin du fichier par rapport à l'assemblée/répertoire exe.

Par exemple, l'assemblée réside à l' "C:\Program Files\Mannequin Dossier\MyProgram" et le fichier "C:\Program Files\Mannequin Dossier\MyProgram\Data\datafile1.dat" alors, j'aimerais qu'elle montre ".\Data\datafile1.dat". Si le fichier est "C:\Program Files\Mannequin Dossier\datafile1.dat", alors je veux "..\datafile1.dat". Mais si le fichier est dans le répertoire de racine ou 1 répertoire en dessous de la racine, puis d'afficher le chemin d'accès complet.

Quelle solution préconisez-vous? Regex?

Fondamentalement, je voulais afficher utiles chemin d'accès au fichier info sans prendre trop d'espace à l'écran.

EDIT: Juste pour préciser un peu plus. Le but de cette solution est d'aider l'utilisateur ou à moi-même savoir quel fichier je n'ai chargé la dernière et à peu près de qui annuaire de. Je suis à l'aide d'un readonly zone de texte pour afficher le chemin d'accès. La plupart du temps, le chemin du fichier est beaucoup plus long que l'espace d'affichage de la zone de texte. Le chemin est supposé être informatif, mais pas assez importante pour faire plus d'espace à l'écran.

Alex Brault commentaire était bon, donc c'est Jonathan Leffler. La fonction Win32 fournis par DavidK seulement aider avec une partie du problème, pas le tout, mais merci quand même. Comme pour James Newton-King solution, je vais essayer plus tard, quand je suis libre.

53voto

ctacke Points 53946

Un peu tard pour la question, mais j’ai juste besoin de cette fonctionnalité aussi bien. Je suis d’accord avec DavidK que puisqu’il n’y a une fonction API intégrée qui prévoit cela, vous devez l’utiliser. Voici un wrapper managé pour elle :

25voto

DavidK Points 2741

Il y a une fonction Win32 dans shlwapi.dll qui fait exactement ce que vous voulez : PathRelativePathTo() : http://msdn.microsoft.com/en-us/library/bb773740(VS.85).aspx

Je ne suis pas au courant de toute façon d’accéder à cette de .NET autrement qu’à P/Invoke, bien que.

9voto

James Newton-King Points 13880

J’ai utilisé cela dans le passé.

5voto

Jonathan Leffler Points 299946

Comme Alex Brault points, notamment sur Windows, le chemin d'accès absolu (avec la lettre de lecteur et tout et tout) est sans ambiguïté, et souvent mieux.

Ne devrait pas votre OpenFileDialog d'utiliser un arbre-navigateur structure?

Pour obtenir un peu de la nomenclature en place, le RefDir est le répertoire par rapport à laquelle vous souhaitez spécifier le chemin d'accès; la AbsName est le chemin absolu du nom que vous voulez à la carte; et les RelPath est le chemin d'accès relatif.

Prendre la première de ces options qui correspond à:

  • Si vous avez une lettre de lecteur différente, il n'y a pas de chemin relatif à partir de RefDir à AbsName; vous devez utiliser le AbsName.
  • Si le AbsName est dans un sous-répertoire de RefDir ou est un fichier dans RefDir puis retirez simplement le RefDir depuis le début de AbsName pour créer RelPath; en option, ajouter le préfixe "./" (ou ".\" puisque vous êtes sur Windows).
  • Trouver le plus long préfixe commun de RefDir et AbsName (où D:\Abc\Def et D:\Abc\Default partager D:\Abc comme le plus long préfixe commun; il doit être un mappage de nom des composants, et pas un simple plus longue sous-chaîne commune); l'appeler LCP. Supprimer LCP à partir de AbsName et RefDir. Pour chaque élément de chemin à gauche (RefDir - LCP), prepend ".. \ " (AbsName - LCP) pour donner RelPath.

Pour illustrer la dernière règle (qui est, bien sûr, de loin le plus complexe), pour commencer:

RefDir = D:\Abc\Def\Ghi
AbsName = D:\Abc\Default\Karma\Crucible

Alors

LCP = D:\Abc
(RefDir - LCP) = Def\Ghi
(Absname - LCP) = Default\Karma\Crucible
RelPath = ..\..\Default\Karma\Crucible

Alors que j'etais en train de taper, DavidK produit une réponse qui suggère que vous n'êtes pas les premiers à avoir besoin de cette fonction et qu'il n'y est une fonction standard pour faire ce travail. L'utiliser. Mais il n'y a pas de mal à être capable de penser votre chemin à travers des principes premiers.

Sauf que les systèmes Unix ne prennent pas en charge les lettres de lecteur (donc tout est toujours situé sous le même répertoire racine, et la première balle est donc hors de propos), la même technique peut être utilisée sur Unix.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X