在C#中从路径中移除驱动器(或网络名称)

29

什么是最简洁(但安全)的方法,在C#中从绝对路径中删除驱动器名称、网络路径等?

例如,将以下内容转换:

\\networkmachine\foo\bar
或者
C:\foo\bar

要转换为\foo\bar

看起来已经有很多关于路径问题的答案了,但我还是没有找到我想要的。 我自己首先想到的是使用Path.GetFullPath()来确保我确实在使用绝对路径,然后只需使用正则表达式查找不与另一个斜杠相邻的第一个斜杠。 但是,使用正则表达式进行路径操作似乎有些危险。

也许更明智的做法是获取驱动器号/目标网络机器等,将字符串转换为Uri,然后请求相对于驱动器/机器的路径,然后再将其转换回字符串? 还是有更好的方法吗?


1
我已经编写了自己的辅助函数来处理这个问题。只是一些 if...else 和字符串操作。 - Uwe Keim
1
那么与我们分享这些方法可能会很好。否则,你的评论是毫无用处的 :) - Jan Sverre
3
你可以从Path.GetPathRoot()返回的字符串中去掉路径的开头,但这也会将网络路径中的“foo”(共享名称)一并去掉。 - DeCaf
2
或者,如果您需要进行大量这些操作,您可能想要查看 http://alphafs.codeplex.com/,其中包含一些额外的路径操作选项,这些选项不仅提供了.NET提供的选项,还支持扩展路径(也不在标准.NET中提供)。 - DeCaf
5个回答

43

使用

string MyPath = @""; // \\networkmachine\foo\bar OR C:\foo\bar
string MyPathWithoutDriveOrNetworkShare = MyPath.Substring (Path.GetPathRoot(MyPath).Length);

对于 C:\foo\bar 的结果应为 foo\bar,对于 \\networkmachine\foo\bar 的结果应为 bar

有关 MSDN 参考,请参见 http://msdn.microsoft.com/en-us/library/system.io.path.getpathroot.aspx

编辑 - 根据评论:

通过 "字符串魔法" (在我看来并不简洁,因此不建议使用)可以做到这一点:

if ( ( MyPath.IndexOf (":") == 1 ) || ( MyPath.IndexOf ( "\\\\" ) == 0 ) )
     { MyPathWithoutDriveOrNetworkShare = MyPath.Substring (2); }
if ( MyPathWithoutDriveOrNetworkShare.IndexOf ( "\\" ) > 0 )
     MyPathWithoutDriveOrNetworkShare = MyPathWithoutDriveOrNetworkShare.Substring ( MyPathWithoutDriveOrNetworkShare.IndexOf ( "\\" ) );  

10
但这并不能给出他在网络路径示例中所要求的路径,因为在这种情况下,GetPathRoot将返回\networkmachine\foo。 - DeCaf

2

0

我认为这会起作用
这段代码使用了递归函数调用

仅适用于文件夹或文件路径

//unRootedPath= PathHelper.GetPathWithoutRoot("C:\foo\bar"); => "foo\bar"

 public static class PathHelper
{

     public static string GetPathWithoutRoot(string orgPath)
    {
        if (!Path.IsPathRooted(orgPath))
        {
            return orgPath;
        }
        return GetPathWithoutRoot(new DirectoryInfo(orgPath));
    }

    public static string GetPathWithoutRoot(DirectoryInfo dirInfo)
    {
        if (dirInfo.Parent == null)
        {
            return string.Empty;//here recursion will stop
        }

        var parent = GetPathWithoutRoot(dirInfo.Parent);//Call same function (Recursion)
        if (string.IsNullOrEmpty(parent))
        {
            return dirInfo.Name;//here start write path without root("C:\")
        }
        else
        {
            return Path.Combine(parent, dirInfo.Name);
        }
    }

目前你的回答不够清晰,请编辑并添加更多细节,以帮助其他人理解它如何回答问题。你可以在帮助中心找到有关如何编写好答案的更多信息。 - Community

0
我不知道安全性方面的问题,但我个人会将它放入一个字符串中,查找包含“\\”或“:”的内容,并通过在它们周围进行子字符串处理来删除它们。

0
根据请求,这是我如何做到的:
我编写了一个帮助程序class PathHelper,它可以实现我认为提问者想要知道的功能。
你可以在CodeProject上找到该库,我将使用PathHelper.GetDriveOrShare函数,类似于以下方式:
var s = @"C:\foo\bar";
var withoutRoot = s.Substring( PathHelper.GetDriveOrShare(s).Length ); 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接