Path. Gabungkan absolute dengan string path relatif

96

Saya mencoba untuk bergabung dengan jalur Windows dengan jalur relatif menggunakan Path.Combine.

Namun, Path.Combine(@"C:\blah",@"..\bling")kembali C:\blah\..\blingbukan C:\bling\.

Adakah yang tahu bagaimana mencapai ini tanpa menulis pemecah jalan relatif saya sendiri (yang seharusnya tidak terlalu sulit)?

CVertex
sumber
5
Kami mendapatkan jawaban yang berbeda di sini .. Saya rasa ini bukan duplikat
CVertex
1
itu duplikat, meskipun menurut saya Path.GetFullName adalah solusi yang lebih baik.
Greg Dean
Anda baru saja mengkontradiksi diri Anda sendiri. Tapi terima kasih atas jawaban alternatifnya.
CVertex
kemungkinan duplikat Path.Combine dan notasi titik
Julien Bérubé

Jawaban:

64

Pekerjaan apa:

string relativePath = "..\\bling.txt";
string baseDirectory = "C:\\blah\\";
string absolutePath = Path.GetFullPath(baseDirectory + relativePath);

(hasil: absolutePath = "C: \ bling.txt")

Apa yang tidak berhasil

string relativePath = "..\\bling.txt";
Uri baseAbsoluteUri = new Uri("C:\\blah\\");
string absolutePath = new Uri(baseAbsoluteUri, relativePath).AbsolutePath;

(hasil: absolutePath = "C: /blah/bling.txt")

Llyle
sumber
8
Ya, itulah yang saya
sindir
7
Pastikan saja baseDirectory memiliki \\ trailing, jika tidak Anda akan berakhir dengan C:\\blah..\\bling.txtdan itu tidak berhasil. Dalam hal ini Anda dapat menambahkannya secara manual ke string atau lakukanPath.GetFullPath(Path.Combine(baseDirectory, relativePath))
Nelson Rothermel
5
Bukankah hasil dari bagian What Works Anda seharusnya C:\bling.txt?
cod3monk3y
Mengapa metode berbasis URI tidak berfungsi? Menurut jawaban ini , hasilnya valid (dan tampaknya juga dikenali di Windows ).
FH
38

Panggil Path.GetFullPath di jalur gabungan http://msdn.microsoft.com/en-us/library/system.io.path.getfullpath.aspx

> Path.GetFullPath(Path.Combine(@"C:\blah\",@"..\bling"))
C:\bling

(Saya setuju Path.Combine harus melakukan ini sendiri)

Kolonel Panic
sumber
Perhatikan bahwa ini hanya berfungsi jika jalur pertama adalah jalur absolut. Ini tidak berhasil untukPath.GetFullPath(Path.Combine(@"..\..\blah",@"\bling"))
derekantrican
17

Path.GetFullPath(@"c:\windows\temp\..\system32")?

shahkalpesh.dll
sumber
2
Catatan: harus menghasilkanc:\windows\system32
cod3monk3y
4

Untuk aplikasi universal windows Path.GetFullPath()tidak tersedia, Anda dapat menggunakan System.Urikelas sebagai gantinya:

 Uri uri = new Uri(Path.Combine(@"C:\blah\",@"..\bling"));
 Console.WriteLine(uri.LocalPath);
kunci jempol
sumber
3

Ini akan memberi Anda apa yang Anda butuhkan (jalur TIDAK harus ada agar ini berfungsi)

DirectoryInfo di = new DirectoryInfo(@"C:\blah\..\bling");
string cleanPath = di.FullName;
Jonathan Mc Namee
sumber
1
Path.GetFullPath () dan DirectoryInfo.FullName akan bekerja di jalur fiktif. Masalahnya adalah ketika file tersebut benar-benar ada, proses eksekusi membutuhkan FileIOPermission - true untuk kedua API tersebut. (lihat MSDN)
Paul Williams
1

Hati-hati dengan garis miring terbalik, jangan lupakan (jangan gunakan dua kali :)

string relativePath = "..\\bling.txt";
string baseDirectory = "C:\\blah\\";
//OR:
//string relativePath = "\\..\\bling.txt";
//string baseDirectory = "C:\\blah";
//THEN
string absolutePath = Path.GetFullPath(baseDirectory + relativePath);
zaknafein
sumber
0

Path.GetFullPath() tidak bekerja dengan jalur relatif.

Inilah solusi yang berfungsi dengan jalur relatif + absolut. Ia bekerja di kedua Linux + Windows dan tetap ..seperti yang diharapkan di awal teks (diam mereka akan dinormalisasi). Solusinya masih mengandalkanPath.GetFullPath melakukan perbaikan dengan solusi kecil.

Ini adalah metode ekstensi jadi gunakan seperti text.Canonicalize()

/// <summary>
///     Fixes "../.." etc
/// </summary>
public static string Canonicalize(this string path)
{
    if (path.IsAbsolutePath())
        return Path.GetFullPath(path);
    var fakeRoot = Environment.CurrentDirectory; // Gives us a cross platform full path
    var combined = Path.Combine(fakeRoot, path);
    combined = Path.GetFullPath(combined);
    return combined.RelativeTo(fakeRoot);
}
private static bool IsAbsolutePath(this string path)
{
    if (path == null) throw new ArgumentNullException(nameof(path));
    return
        Path.IsPathRooted(path)
        && !Path.GetPathRoot(path).Equals(Path.DirectorySeparatorChar.ToString(), StringComparison.Ordinal)
        && !Path.GetPathRoot(path).Equals(Path.AltDirectorySeparatorChar.ToString(), StringComparison.Ordinal);
}
private static string RelativeTo(this string filespec, string folder)
{
    var pathUri = new Uri(filespec);
    // Folders must end in a slash
    if (!folder.EndsWith(Path.DirectorySeparatorChar.ToString())) folder += Path.DirectorySeparatorChar;
    var folderUri = new Uri(folder);
    return Uri.UnescapeDataString(folderUri.MakeRelativeUri(pathUri).ToString()
        .Replace('/', Path.DirectorySeparatorChar));
}
U. Bulle
sumber