C# 如何制作相对于特定文件夹的绝对路径?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9042861/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to make an absolute path relative to a particular folder?
提问by asmo
For example, how can I make this
例如,我怎样才能做到这一点
"C:\RootFolder\SubFolder\MoreSubFolder\LastFolder\SomeFile.txt"
relative to this folder
相对于这个文件夹
"C:\RootFolder\SubFolder\"
if the expected result is
如果预期的结果是
"MoreSubFolder\LastFolder\SomeFile.txt"
采纳答案by ordag
Yes, you can do that, it's easy, think of your paths as URIs:
是的,您可以这样做,这很容易,将您的路径视为 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"
回答by dasblinkenlight
In your example, it's simply absPath.Substring(relativeTo.Length).
在您的示例中,它只是absPath.Substring(relativeTo.Length).
More elaborate example would require going back a few levels from the relativeTo, as follows:
更详细的示例需要从 返回几个级别relativeTo,如下所示:
"C:\RootFolder\SubFolder\MoreSubFolder\LastFolder\SomeFile.txt"
"C:\RootFolder\SubFolder\Sibling\Child\"
The algorithm to make a relative path would look as follows:
生成相对路径的算法如下所示:
- Remove the longest common prefix (in this case, it is
"C:\RootFolder\SubFolder\") - Count the number of folders in
relativeTo(in this case, it is 2:"Sibling\Child\") - Insert
..\for each remaining folder - Concatenate with the remainder of the absolute path after the suffix removal
- 删除最长的公共前缀(在本例中为
"C:\RootFolder\SubFolder\") - 计算文件夹的数量
relativeTo(在这种情况下,它是 2:"Sibling\Child\") ..\为每个剩余的文件夹插入- 去除后缀后与绝对路径的剩余部分连接
The end result looks like this:
最终结果如下所示:
"..\..\MoreSubFolder\LastFolder\SomeFile.txt"
回答by TarmoPikaro
Here is my 5-cents without using any special Url class for that purpose.
这是我的 5 美分,没有为此使用任何特殊的 Url 类。
Search for makeRelativein following git repository: https://github.com/tapika/syncProj/blob/8ea41ebc11f538a22ed7cfaf59a8b7e0b4c3da37/syncProj.cs#L1685
makeRelative在以下 git 存储库中搜索:https: //github.com/tapika/syncProj/blob/8ea41ebc11f538a22ed7cfaf59a8b7e0b4c3da37/syncProj.cs#L1685
(Fixed version frozen once upon a time, search latest version separately)
(固定版本曾被冻结,请单独搜索最新版本)
I'll fix bugs if there is any.
如果有bug,我会修复。
Here is copy of same code as in link above:
这是与上面链接中相同代码的副本:
/// <summary>
/// Rebases file with path fromPath to folder with baseDir.
/// </summary>
/// <param name="_fromPath">Full file path (absolute)</param>
/// <param name="_baseDir">Full base directory path (absolute)</param>
/// <returns>Relative path to file in respect of baseDir</returns>
static public String makeRelative(String _fromPath, String _baseDir)
{
String pathSep = "\";
String fromPath = Path.GetFullPath(_fromPath);
String baseDir = Path.GetFullPath(_baseDir); // If folder contains upper folder references, they gets lost here. "c:\test\..\test2" => "c:\test2"
String[] p1 = Regex.Split(fromPath, "[\\/]").Where(x => x.Length != 0).ToArray();
String[] p2 = Regex.Split(baseDir, "[\\/]").Where(x => x.Length != 0).ToArray();
int i = 0;
for (; i < p1.Length && i < p2.Length; i++)
if (String.Compare(p1[i], p2[i], true) != 0) // Case insensitive match
break;
if (i == 0) // Cannot make relative path, for example if resides on different drive
return fromPath;
String r = String.Join(pathSep, Enumerable.Repeat("..", p2.Length - i).Concat(p1.Skip(i).Take(p1.Length - i)));
return r;
}

