2012-01-28 25 views
17

Ví dụ, làm thế nào tôi có thể làm cho điều nàyLàm cách nào để tạo đường dẫn tuyệt đối liên quan đến một thư mục cụ thể?

"C:\RootFolder\SubFolder\MoreSubFolder\LastFolder\SomeFile.txt" 

tương đối so với thư mục này

"C:\RootFolder\SubFolder\" 

nếu kết quả dự kiến ​​là

"MoreSubFolder\LastFolder\SomeFile.txt" 
+0

Kết quả mong đợi không phải là "MoreSubFolder \ LastFolder \ SomeFile.txt"? –

+0

Cảm ơn Yup vì đã chỉ ra sai lầm của tôi! – asmo

+0

Bạn cần phải nói lại cụm từ này. Tôi đọc nó hai lần, và tôi vẫn không chắc chắn những gì bạn muốn thực sự.Nếu không, tôi bị cám dỗ trả lời: sử dụng các phương thức IndexOf và Substring để lấy phần thứ 2 của đường dẫn (hoặc để loại bỏ phần thứ nhất của đường dẫn) - và tôi có cảm giác đó không phải là thứ bạn muốn. Xem xét các phương thức tĩnh của lớp System.IO.Path - nó có một vài trình trợ giúp tốt để kết hợp các đường dẫn và tương tự. –

Trả lời

28

Có, bạn có thể làm điều đó , thật dễ dàng, nghĩ đường dẫn của bạn là URI:

Uri fullPath = new Uri(@"C:\RootFolder\SubFolder\MoreSubFolder\LastFolder\SomeFile.txt", UriKind.Absolute); 
Uri relRoot = new Uri(@"C:\RootFolder\SubFolder\", UriKind.Absolute); 

string relPath = relRoot.MakeRelativeUri(fullPath).ToString(); 
// relPath == @"MoreSubFolder\LastFolder\SomeFile.txt" 
+4

Không hoạt động với không gian: https://ideone.com/cLe7wf –

+3

'relPath = Uri.UnescapeDataString (relPath)' để sửa không gian. –

+0

Nếu đường dẫn gốc không kết thúc bằng "\" thì phần cuối cùng của đường dẫn gốc sẽ không bị xóa khỏi đường dẫn đầy đủ! –

11

Trong ví dụ của bạn, nó chỉ đơn giản là absPath.Substring(relativeTo.Length).

dụ More phức tạp đòi hỏi phải đi lại một vài cấp độ từ relativeTo, như sau:

"C:\RootFolder\SubFolder\MoreSubFolder\LastFolder\SomeFile.txt" 
"C:\RootFolder\SubFolder\Sibling\Child\" 

Thuật toán để thực hiện một đường dẫn tương đối sẽ trông như sau:

  • Tháo chung dài nhất tiền tố (trong trường hợp này, nó là "C:\RootFolder\SubFolder\")
  • Đếm số lượng thư mục trong relativeTo (trong trường hợp này, nó là 2: "Sibling\Child\")
  • Chèn ..\ cho mỗi thư mục còn lại
  • CONCATENATE với phần còn lại của đường dẫn tuyệt đối sau khi loại bỏ hậu tố

Kết quả cuối cùng trông như thế này:

"..\..\MoreSubFolder\LastFolder\SomeFile.txt" 
+1

Hoặc "xóa tiền tố chung dài nhất kết thúc bằng dấu gạch chéo". –

-2

Tại sao tất cả các giải pháp phức tạp này?
Và liên quan đến Uri? Có thật không ? Bạn sẽ không phải đợi lâu cho ngoại lệ đầu tiên.
Có sự sáng chói trong sự đơn giản.
Không cần thêm bất kỳ lớp khung công tác bổ sung nào.

public static string BuildRelativePath(string absolutePath, string basePath) 
    { 
     return absolutePath.Substring(basePath.Length); 
    } 

Và chỉ trong trường hợp bạn không thể quản lý để luôn thêm hoặc để luôn luôn bỏ qua System.IO.Path.DirectorySeparatorChar đóng cửa để dây của bạn, hoặc bạn không thể không trộn lẫn các đối số:

public static string FaultTolerantRelativePath(string absolutePath, string basePath) 
{ 
    if(absolutePath == null || basePath == null) 
     return null; 

    absolutePath = absolutePath.Replace(System.IO.Path.DirectorySeparatorChar, '/'); 
    basePath = basePath.Replace(System.IO.Path.DirectorySeparatorChar, '/'); 

    if (!basePath.EndsWith("/")) 
     basePath += "/"; 

    if (!absolutePath.EndsWith("/")) 
     absolutePath += "/"; 

    if (absolutePath.Length < basePath.Length) 
     throw new ArgumentException("absolutePath.Length < basePath.Length ? This can't be. You mixed up absolute and base path."); 

    string resultingPath = absolutePath.Substring(basePath.Length); 
    resultingPath = resultingPath.Replace('/', System.IO.Path.DirectorySeparatorChar); 

    return resultingPath; 
} 
+2

Tôi đồng ý với tác giả - tại sao các giải pháp phức tạp liên quan đến lớp Uri? Lỗi quá mức. Nhưng giải pháp này sẽ không chơi tốt trong mọi trường hợp - cần phải có giải pháp tốt hơn. – TarmoPikaro

1

Đây là 5 xu mà không sử dụng bất kỳ lớp Url đặc biệt nào cho mục đích đó.

Tìm kiếm makeRelative ở sau kho svn:

https://sourceforge.net/p/syncproj/code/HEAD/tree/syncProj.cs#l976

tôi sẽ sửa lỗi nếu có bất kỳ.

+0

Xin lỗi, nhưng điều này dường như không hoạt động 'makeRelative (@" F: \ a \ b ", @" F: \ ")' ví dụ trả về '.. \ b' (thay vì' a \ b') – Mikescher

+0

Bạn có thể thử lại - Tôi đã cập nhật phiên bản mới nhất của mình chưa? Nếu nó không hoạt động, tôi sẽ sửa chữa nó. – TarmoPikaro

+0

Đúng, có vẻ đúng. Chúc mừng. – Mikescher

Các vấn đề liên quan