如何制作相对于特定文件夹的绝对路径?

例如,我该怎么做呢

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

相对于此文件夹

 "C:\RootFolder\SubFolder\" 

如果预期的结果是

 "MoreSubFolder\LastFolder\SomeFile.txt" 

是的,您可以这样做,很容易, 将您的路径视为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" 

在您的示例中,它只是absPath.Substring(relativeTo.Length)

更详细的例子需要从relativeTo返回几个级别,如下所示:

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

制作相对路径的算法如下所示:

  • 删除最长的公共前缀(在这种情况下,它是"C:\RootFolder\SubFolder\"
  • 计算relativeTo的文件夹数量(在这种情况下,它是2: "Sibling\Child\"
  • 为剩下的每个文件夹插入..\
  • 在删除后缀后与绝对路径的其余部分连接

最终结果如下:

 "..\..\MoreSubFolder\LastFolder\SomeFile.txt" 

这是我的5美分没有使用任何特殊的Url类为此目的。

在以下svn存储库中搜索makeRelative:

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

我会修复bug,如果有的话。

为什么所有这些复杂的解
并涉及到Uri? 真的吗? 您不必等待第一个例外。
简洁明了。
不需要任何额外的框架类。

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

并且万一你无法总是添加或总是省略关闭System.IO.Path.DirectorySeparatorChar到你的字符串,或者你不能混淆参数:

 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; }