Yol Mutlakı göreli yol dizeleriyle birleştirin


98

Kullanarak göreli bir yol ile bir Windows yoluna katılmaya çalışıyorum Path.Combine.

Ancak, yerine Path.Combine(@"C:\blah",@"..\bling")döner .C:\blah\..\blingC:\bling\

Kendi göreceli yol çözümleyicimi yazmadan bunu nasıl başaracağını bilen var mı (ki bu çok zor olmamalı)?



5
Burada farklı cevaplar alıyoruz .. Yinelenen olduğunu sanmıyorum
CVertex

1
Path.GetFullName'in daha iyi bir çözüm olduğunu düşünmeme rağmen, yineleniyor.
Greg Dean

Kendinle çelişiyorsun. Ama alternatif cevap için teşekkürler.
CVertex

Yanıtlar:


67

Ne çalışıyor:

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

(sonuç: absolutePath = "C: \ bling.txt")

Ne çalışmıyor

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

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


8
Evet,
gönderide

8
Sadece baseDirectory'nin sonda \\ yazdığından emin olun, aksi takdirde elde edersiniz C:\\blah..\\bling.txtve bu çalışmaz. Bu durumda, bunları dizeye manuel olarak ekleyebilir veya doPath.GetFullPath(Path.Combine(baseDirectory, relativePath))
Nelson Rothermel 06.06.2013

5
What Works bölümünüzün sonucu olması gerekmiyor C:\bling.txtmu?
cod3monk3y

URI tabanlı yöntem neden çalışmıyor? Bu yanıta göre sonuç geçerlidir (ve Windows'ta da tanınıyor gibi görünüyor ).
FH



4

Windows için evrensel uygulamalar Path.GetFullPath()mevcut değildir, System.Uribunun yerine sınıfı kullanabilirsiniz :

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

3

Bu size tam olarak ihtiyacınız olanı verecektir (bunun çalışması için yolun var olması gerekmez)

DirectoryInfo di = new DirectoryInfo(@"C:\blah\..\bling");
string cleanPath = di.FullName;

1
Hem Path.GetFullPath () hem de DirectoryInfo.FullName hayali bir yolda çalışacaktır. Sorun, dosya gerçekten mevcut olduğunda, yürütme işleminin FileIOPermission'a ihtiyaç duymasıdır - her iki API için de geçerlidir. (bkz. MSDN)
Paul Williams

1

Ters eğik çizgiler konusunda dikkatli olun, onları unutmayın (iki kez kullanmayın :)

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

1

Path.GetFullPath() göreli yollarla çalışmaz.

Hem göreli hem de mutlak yollarla çalışan çözüm burada. Hem Linux + Windows üzerinde çalışır ..ve metnin başında beklendiği gibi tutar (dinlenme durumunda normalleştirilecektir). Çözüm hala güveniyorPath.GetFullPath , düzeltmeyi küçük bir geçici yapmaya ediyor.

Bu bir uzatma yöntemidir, bu yüzden onu 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));
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.