Il y a une partie dans mes applications qui affiche le chemin du fichier chargé par l'utilisateur via OpenFileDialog. Cela prend trop de place pour afficher le chemin complet, mais je ne veux pas afficher uniquement le nom du fichier car il peut être ambigu. Je préférerais donc afficher le chemin du fichier par rapport au répertoire assembly / exe.
Par exemple, l'assemblage réside à C:\Program Files\Dummy Folder\MyProgram
et le fichier à C:\Program Files\Dummy Folder\MyProgram\Data\datafile1.dat
alors je voudrais qu'il s'affiche .\Data\datafile1.dat
. Si le fichier est dans C:\Program Files\Dummy Folder\datafile1.dat
, alors je voudrais ..\datafile1.dat
. Mais si le fichier se trouve dans le répertoire racine ou dans 1 répertoire sous la racine, affichez le chemin complet.
Quelle solution recommanderiez-vous? Regex?
Fondamentalement, je veux afficher des informations utiles sur le chemin du fichier sans prendre trop d'espace à l'écran.
EDIT: Juste pour clarifier un peu plus. Le but de cette solution est d'aider l'utilisateur ou moi-même à savoir de quel fichier j'ai chargé en dernier et à peu près de quel répertoire provient-il. J'utilise une zone de texte en lecture seule pour afficher le chemin. 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 censé être informatif mais pas assez important pour occuper plus d'espace à l'écran.
Le commentaire d'Alex Brault était bon, tout comme Jonathan Leffler. La fonction Win32 fournie par DavidK n'aide qu'une partie du problème, pas la totalité, mais merci quand même. Quant à la solution James Newton-King, je vais l'essayer plus tard quand je serai libre.
Réponses:
.NET Core 2.0 a
Path.GetRelativePath
, sinon, utilisez ceci.la source
return relativeUri.ToString().Replace('/',Path.DirectorySeparatorChar);
c:\test
etc:\test\abc.txt
ça revienttest\abc.txt
ce qui n'est pas relatif à mon avis. Je m'attendrais justeabc.txt
Un peu tard à la question, mais j'avais juste besoin de cette fonctionnalité aussi. Je suis d'accord avec DavidK pour dire que, comme il existe une fonction API intégrée qui fournit cela, vous devez l'utiliser. Voici un wrapper géré pour cela:
la source
Réponse .NET Core 2.0
.NET Core 2.0 a Path.GetRelativePath qui peut être utilisé comme ceci:
Dans l'exemple ci-dessus, la
relativePath
variable est égale àData\datafile1.dat
.Réponse alternative .NET
La solution de @ Dave ne fonctionne pas lorsque les chemins de fichiers ne se terminent pas par une barre oblique (
/
), ce qui peut arriver si le chemin est un chemin de répertoire. Ma solution résout ce problème et utilise également laUri.UriSchemeFile
constante au lieu du codage en dur"FILE"
.Réponse Windows Interop
Il existe une API Windows appelée PathRelativePathToA qui peut être utilisée pour rechercher un chemin relatif. Veuillez noter que les chemins de fichier ou de répertoire que vous transmettez à la fonction doivent exister pour qu'elle fonctionne.
la source
AltDirectorySeparatorChar
c'est une possibilité, ne devriez-vous pas laAppendDirectorySeparatorChar
vérifier aussi?Il existe une fonction Win32 (C ++) dans shlwapi.dll qui fait exactement ce que vous voulez:
PathRelativePathTo()
Je ne connais aucun moyen d'accéder à cela à partir de .NET autre que P / Invoke, cependant.
la source
shlwapi.dll
sont désormais obsolètes msdn.microsoft.com/en-us/library/windows/desktop"These functions are available through Windows XP Service Pack 2 (SP2) and Windows Server 2003. They might be altered or unavailable in subsequent versions of Windows."
Si vous utilisez .NET Core 2.0,
Path.GetRelativePath()
est disponible en fournissant cette fonctionnalité spécifique:Sinon, pour le framework complet .NET (à partir de la v4.7), il est recommandé d'utiliser l'une des autres réponses suggérées.
la source
J'ai utilisé cela dans le passé.
la source
Comme le souligne Alex Brault, en particulier sous Windows, le chemin absolu (avec lettre de lecteur et tout) est sans ambiguïté et souvent meilleur.
Votre OpenFileDialog ne devrait-il pas utiliser une structure arborescente régulière?
Pour mettre en place une nomenclature, le RefDir est le répertoire par rapport auquel vous souhaitez spécifier le chemin; le AbsName est le nom du chemin absolu que vous souhaitez mapper; et le RelPath est le chemin relatif résultant.
Prenez la première de ces options qui correspond:
Pour illustrer la dernière règle (qui est, bien entendu, de loin la plus complexe), commencez par:
ensuite
Pendant que je tapais, DavidK a produit une réponse qui suggère que vous n'êtes pas le premier à avoir besoin de cette fonctionnalité et qu'il existe une fonction standard pour faire ce travail. Utilise le. Mais il n'y a pas non plus de mal à pouvoir réfléchir à partir des premiers principes.
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 puce n'est donc pas pertinente), la même technique pourrait être utilisée sous Unix.
la source
C'est un long chemin, mais la classe System.Uri a une méthode nommée MakeRelativeUri. Vous pourriez peut-être l'utiliser. C'est vraiment dommage que System.IO.Path ne l'ait pas.
la source
Comme indiqué ci-dessus .NET Core 2.x a une implémentation de
Path.GetRelativePath
.Le code ci-dessous est adapté des sources et fonctionne correctement avec .NET 4.7.1 Framework.
la source
J'utilise ceci:
la source
Utilisation:
la source
path.Replace(rootPath.TrimEnd('\\') + "\\", "")
.Si vous êtes sûr que votre chemin absolu 2 est toujours relatif au chemin absolu, supprimez simplement les N premiers caractères de chemin2, où N est la longueur de chemin1.
la source
Vous souhaitez utiliser la
CommonPath
méthode de cetteRelativePath
classe. Une fois que vous avez le chemin commun, supprimez-le simplement du chemin que vous souhaitez afficher.la source
Je diviserais vos deux chemins au niveau du répertoire. À partir de là, trouvez le point de divergence et revenez au dossier d'assemblage, en ajoutant un «../» à chaque fois que vous passez un répertoire.
Gardez toutefois à l'esprit qu'un chemin absolu fonctionne partout et est généralement plus facile à lire qu'un chemin relatif. Personnellement, je ne montrerais pas à un utilisateur un chemin relatif à moins que cela ne soit absolument nécessaire.
la source
Si vous savez que toPath est contenu par fromPath, vous pouvez rester simple. Je vais laisser de côté les affirmations par souci de concision.
la source
La fonction qui utilise l'URI a renvoyé un chemin relatif "presque". Il comprenait un répertoire contenant directement le fichier dont le chemin relatif que je voulais obtenir.
Il y a quelque temps, j'ai écrit une fonction simple qui renvoie le chemin relatif du dossier ou du fichier, et même si c'est sur un autre lecteur, elle inclut également la lettre du lecteur.
S'il vous plaît, jetez un oeil:
la source
Si vous avez une zone de texte en lecture seule, ne pourriez-vous pas en faire une étiquette et définir AutoEllipsis = true?
alternativement, il y a des articles avec du code pour générer vous-même l'autoellipse: (cela le fait pour une grille, vous auriez besoin de passer la largeur de la zone de texte à la place. Ce n'est pas tout à fait correct car il pirate un peu plus que nécessaire , et je n'ai pas réussi à trouver où le calcul est incorrect. Il serait assez facile de modifier pour supprimer la première partie du répertoire plutôt que la dernière si vous le désirez.
la source
la source
Cela devrait fonctionner:
la source
Façon avec Uri ne fonctionnait pas sur les systèmes linux / macOS. Le chemin «/ var / www / root» ne peut pas être converti en Uri. De manière plus universelle - faites tout à la main.
PS: j'utilise "/" comme valeur par défaut du séparateur au lieu de Path.DirectorySeparatorChar, car le résultat de cette méthode est utilisé comme uri dans mon application.
la source
Voici la mienne:
la source
Jouez avec quelque chose comme:
Et testez-le
la source
Dans
ASP.NET Core 2
, si vous voulez le chemin d'accès relatif,bin\Debug\netcoreapp2.2
vous pouvez utiliser la combinaison suivante:la source