In meinen Apps gibt es einen Teil, der den vom Benutzer über OpenFileDialog geladenen Dateipfad anzeigt. Es nimmt zu viel Platz ein, um den gesamten Pfad anzuzeigen, aber ich möchte nicht nur den Dateinamen anzeigen, da dieser möglicherweise nicht eindeutig ist. Daher würde ich lieber den Dateipfad relativ zum Assembly / exe-Verzeichnis anzeigen.
Zum Beispiel befindet sich die Assembly bei C:\Program Files\Dummy Folder\MyProgram
und die Datei bei, die C:\Program Files\Dummy Folder\MyProgram\Data\datafile1.dat
ich dann anzeigen möchte .\Data\datafile1.dat
. Wenn die Datei in ist C:\Program Files\Dummy Folder\datafile1.dat
, dann würde ich wollen ..\datafile1.dat
. Befindet sich die Datei jedoch im Stammverzeichnis oder in einem Verzeichnis unter dem Stammverzeichnis, wird der vollständige Pfad angezeigt.
Welche Lösung würden Sie empfehlen? Regex?
Grundsätzlich möchte ich nützliche Dateipfadinformationen anzeigen, ohne zu viel Platz auf dem Bildschirm zu beanspruchen.
EDIT: Nur um ein bisschen mehr zu klären. Der Zweck dieser Lösung besteht darin, dem Benutzer oder mir zu helfen, zu wissen, aus welcher Datei ich zuletzt geladen habe und aus welchem Verzeichnis sie ungefähr stammt. Ich verwende ein schreibgeschütztes Textfeld, um den Pfad anzuzeigen. In den meisten Fällen ist der Dateipfad viel länger als der Anzeigebereich des Textfelds. Der Pfad soll informativ sein, aber nicht wichtig genug, um mehr Platz auf dem Bildschirm zu beanspruchen.
Der Kommentar von Alex Brault war gut, ebenso Jonathan Leffler. Die von DavidK bereitgestellte Win32-Funktion hilft nur bei einem Teil des Problems, nicht bei dem gesamten, aber trotzdem danke. Die James Newton-King-Lösung werde ich später ausprobieren, wenn ich frei bin.
Antworten:
.NET Core 2.0 hat dies
Path.GetRelativePath
ansonsten verwendet.quelle
return relativeUri.ToString().Replace('/',Path.DirectorySeparatorChar);
c:\test
undc:\test\abc.txt
es kehrt zurück,test\abc.txt
was meiner Meinung nach nicht relativ ist. Ich würde nur erwartenabc.txt
Ein bisschen spät zur Frage, aber ich brauchte auch nur diese Funktion. Ich stimme DavidK zu, dass Sie diese verwenden sollten , da es eine integrierte API-Funktion gibt , die dies bietet. Hier ist ein verwalteter Wrapper dafür:
quelle
.NET Core 2.0 Antwort
.NET Core 2.0 verfügt über Path.GetRelativePath , das wie folgt verwendet werden kann:
Im obigen Beispiel ist die
relativePath
Variable gleichData\datafile1.dat
.Alternative .NET-Antwort
Die Lösung von @ Dave funktioniert nicht, wenn die Dateipfade nicht mit einem Schrägstrich (
/
) enden. Dies kann passieren, wenn der Pfad ein Verzeichnispfad ist. Meine Lösung behebt dieses Problem und verwendet auch dieUri.UriSchemeFile
Konstante anstelle der harten Codierung"FILE"
.Windows Interop Antwort
Es gibt eine Windows-API namens PathRelativePathToA , mit der ein relativer Pfad gefunden werden kann. Bitte beachten Sie, dass die Datei- oder Verzeichnispfade, die Sie an die Funktion übergeben, vorhanden sein müssen, damit sie funktioniert.
quelle
AltDirectorySeparatorChar
eine Möglichkeit ist, sollten Sie nicht auch danachAppendDirectorySeparatorChar
suchen?In shlwapi.dll gibt es eine Win32 (C ++) - Funktion, die genau das tut, was Sie wollen:
PathRelativePathTo()
Mir ist jedoch keine andere Möglichkeit bekannt, über .NET darauf zuzugreifen, als P / Invoke.
quelle
shlwapi.dll
jetzt veraltet sind 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."
Wenn Sie .NET Core 2.0 verwenden,
Path.GetRelativePath()
steht Folgendes zur Verfügung:Andernfalls empfehlen Sie für .NET Full Framework (ab Version 4.7) die Verwendung einer der anderen vorgeschlagenen Antworten.
quelle
Ich habe das in der Vergangenheit benutzt.
quelle
Wie Alex Brault insbesondere unter Windows hervorhebt, ist der absolute Pfad (mit Laufwerksbuchstaben und allem) eindeutig und oft besser.
Sollte Ihr OpenFileDialog nicht eine normale Baumbrowser-Struktur verwenden?
Um eine Nomenklatur zu erstellen, ist RefDir das Verzeichnis, zu dem Sie den Pfad angeben möchten. Der AbsName ist der absolute Pfadname, den Sie zuordnen möchten. und der RelPath ist der resultierende relative Pfad.
Nehmen Sie die erste dieser Optionen, die übereinstimmen:
Um die letzte Regel zu veranschaulichen (die natürlich bei weitem die komplexeste ist), beginnen Sie mit:
Dann
Während ich tippte, gab DavidK eine Antwort, die darauf hinweist, dass Sie nicht der erste sind, der diese Funktion benötigt, und dass es eine Standardfunktion gibt, um diesen Job auszuführen. Benutze es. Aber es schadet auch nicht, sich von den ersten Prinzipien durchdenken zu können.
Abgesehen davon, dass Unix-Systeme keine Laufwerksbuchstaben unterstützen (daher befindet sich immer alles im selben Stammverzeichnis, und das erste Aufzählungszeichen ist daher irrelevant), kann dieselbe Technik unter Unix verwendet werden.
quelle
Es ist ein langer Weg, aber die System.Uri-Klasse hat eine Methode namens MakeRelativeUri. Vielleicht könntest du das gebrauchen. Es ist wirklich eine Schande, dass System.IO.Path dies nicht hat.
quelle
Wie oben erwähnt, hat .NET Core 2.x die Implementierung von
Path.GetRelativePath
.Der folgende Code wurde aus Quellen angepasst und funktioniert problemlos mit .NET 4.7.1 Framework.
quelle
Ich benutze dies:
quelle
Verwenden:
quelle
path.Replace(rootPath.TrimEnd('\\') + "\\", "")
.Wenn Sie sicher sind, dass Ihr absoluter Pfad 2 immer relativ zum absoluten Pfad ist, entfernen Sie einfach die ersten N Zeichen aus Pfad2, wobei N die Länge von Pfad1 ist.
quelle
Sie möchten die
CommonPath
Methode dieserRelativePath
Klasse verwenden. Sobald Sie den gemeinsamen Pfad haben, entfernen Sie ihn einfach aus dem Pfad, den Sie anzeigen möchten.quelle
Ich würde beide Pfade auf Verzeichnisebene aufteilen. Suchen Sie von dort aus den Punkt der Abweichung und arbeiten Sie sich zurück zum Assembly-Ordner, wobei Sie jedes Mal, wenn Sie ein Verzeichnis übergeben, ein '../' voranstellen.
Beachten Sie jedoch, dass ein absoluter Pfad überall funktioniert und normalerweise leichter zu lesen ist als ein relativer. Ich persönlich würde einem Benutzer keinen relativen Pfad anzeigen, es sei denn, dies wäre absolut notwendig.
quelle
Wenn Sie wissen, dass toPath in fromPath enthalten ist, können Sie es einfach halten. Ich werde die Behauptungen der Kürze halber weglassen.
quelle
Die Funktion, die den URI verwendet, hat einen "fast" relativen Pfad zurückgegeben. Es enthielt ein Verzeichnis, das direkt die Datei enthält, deren relativen Pfad ich erhalten wollte.
Vor einiger Zeit habe ich eine einfache Funktion geschrieben, die den relativen Pfad eines Ordners oder einer Datei zurückgibt, und selbst wenn sie sich auf einem anderen Laufwerk befindet, enthält sie auch den Laufwerksbuchstaben.
Bitte sehen Sie sich das an:
quelle
Wenn Sie ein schreibgeschütztes Textfeld haben, können Sie es nicht zu einer Beschriftung machen und AutoEllipsis = true setzen?
Alternativ gibt es Beiträge mit Code zum Generieren der Autoellipse selbst: (Dies geschieht für ein Raster. Sie müssten stattdessen die Breite für das Textfeld übergeben. Es ist nicht ganz richtig, da es etwas mehr abhackt als nötig und ich bin nicht dazu gekommen, herauszufinden, wo die Berechnung falsch ist. Es wäre einfach genug, Änderungen vorzunehmen, um den ersten Teil des Verzeichnisses und nicht den letzten zu entfernen, wenn Sie dies wünschen.
quelle
quelle
Das sollte funktionieren:
quelle
Weg mit Uri nicht auf Linux / MacOS-Systemen funktioniert. Der Pfad '/ var / www / root' kann nicht in Uri konvertiert werden. Universeller Weg - alles von Hand machen.
PS: Ich verwende "/" als Standardwert für Trennzeichen anstelle von Path.DirectorySeparatorChar, da das Ergebnis dieser Methode in meiner App als uri verwendet wird.
quelle
hier ist meins:
quelle
Spielen Sie mit so etwas wie:
Und teste es
quelle
In
ASP.NET Core 2
, wenn Sie den relativen Pfad zu wollen ,bin\Debug\netcoreapp2.2
können Sie die folgende Kombination verwenden:quelle