如何从路径中提取每个文件夹名称?

60 c# string

我的道路是 \\server\folderName1\another name\something\another folder\

如果我不知道路径中有多少个文件夹而且我不知道文件夹名称,如何将每个文件夹名称提取为字符串?

非常感谢

Mat*_*ell 93

string mypath = @"..\folder1\folder2\folder2";
string[] directories = mypath.Split(Path.DirectorySeparatorChar);
Run Code Online (Sandbox Code Playgroud)

编辑:这将返回目录数组中的每个单独的文件夹.你可以得到这样返回的文件夹数量:

int folderCount = directories.Length;
Run Code Online (Sandbox Code Playgroud)

  • 请注意,可能还需要处理[Path.AltDirectorySeparatorChar](http://msdn.microsoft.com/en-us/library/system.io.path.altdirectoryseparatorchar.aspx).(例如,通过`mypath.Split(new [] {Path.DirectorySeparatorChar,Path.AltDirectorySeparatorChar});`) (16认同)
  • 这在像`\\ ticows01\c $\AgArmourFTP`这样的路径上完全破坏了.对不起,但方法太简单了. (11认同)

Jon*_*Jon 28

这在一般情况下是好的:

yourPath.Split(@"\/", StringSplitOptions.RemoveEmptyEntries)
Run Code Online (Sandbox Code Playgroud)

如果路径本身以(反向)斜杠结束(例如"\ foo\bar \"),则返回的数组中没有空元素.但是,您必须确保它yourPath实际上是一个目录而不是文件.你可以找出它是什么,并补偿它是否是这样的文件:

if(Directory.Exists(yourPath)) {
  var entries = yourPath.Split(@"\/", StringSplitOptions.RemoveEmptyEntries);
}
else if(File.Exists(yourPath)) {
  var entries = Path.GetDirectoryName(yourPath).Split(
                    @"\/", StringSplitOptions.RemoveEmptyEntries);
}
else {
  // error handling
}
Run Code Online (Sandbox Code Playgroud)

我相信这涵盖了所有的基础,而不是太迂腐.它将返回一个string[]你可以迭代的东西foreach,依次获取每个目录.

如果要使用常量而不是@"\/"魔术字符串,则需要使用

var separators = new char[] {
  Path.DirectorySeparatorChar,  
  Path.AltDirectorySeparatorChar  
};
Run Code Online (Sandbox Code Playgroud)

然后使用separators而不是@"\/"在上面的代码中.就个人而言,我发现这个过于冗长,很可能不会这样做.

  • 这在 C# 6 中似乎不起作用,并出现以下错误: `path.Split(@"\/", StringSplitOptions.RemoveEmptyEntries); (1,12):错误CS1503:参数1:无法从“string”转换为“char”(1,19):错误CS1503:参数2:无法从“System.StringSplitOptions”转换为“char”。创建一个带有拆分器的新 char[] 确实有效: `path.Split(new char[] { Path.DirectorySeparatorChar }, options: StringSplitOptions.RemoveEmptyEntries);` 确实有效。 (2认同)

Wol*_*370 9

意识到这是一个很老的帖子,但是我看到了它 - 最后我决定使用下面的函数,因为它对当时我正在做的事情进行了比上述任何一项更好:

private static List<DirectoryInfo> SplitDirectory(DirectoryInfo parent)
{
    if (parent == null) return null;
    var rtn = new List<DirectoryInfo>();
    var di = parent;

    while (di.Name != di.Root.Name)
    {
    rtn.Add(new DirectoryInfo(di));
    di = di.Parent;
    }
    rtn.Add(new DirectoryInfo(di.Root));

    rtn.Reverse();
    return rtn;
}
Run Code Online (Sandbox Code Playgroud)


Kel*_*ton 9

我看到你的方法 Wolf5370并举起你.

internal static List<DirectoryInfo> Split(this DirectoryInfo path)
{
    if(path == null) throw new ArgumentNullException("path");
    var ret = new List<DirectoryInfo>();
    if (path.Parent != null) ret.AddRange(Split(path.Parent));
    ret.Add(path);
    return ret;
}
Run Code Online (Sandbox Code Playgroud)

在路径上c:\folder1\folder2\folder3返回

c:\

c:\folder1

c:\folder1\folder2

c:\folder1\folder2\folder3

以该顺序

要么

internal static List<string> Split(this DirectoryInfo path)
{
    if(path == null) throw new ArgumentNullException("path");
    var ret = new List<string>();
    if (path.Parent != null) ret.AddRange(Split(path.Parent));
    ret.Add(path.Name);
    return ret;
}
Run Code Online (Sandbox Code Playgroud)

将返回

c:\

folder1

folder2

folder3


Dan*_*ert 6

有几种表示文件路径的方法。您应该使用该类System.IO.Path来获取操作系统的分隔符,因为它在 UNIX 和 Windows 之间可能有所不同。另外,大多数(或全部,如果我没记错的话).NET 库接受“\”或“/”作为路径分隔符,无论操作系统如何。因此,我将使用 Path 类来分割您的路径。尝试如下操作:

string originalPath = "\\server\\folderName1\\another\ name\\something\\another folder\\";
string[] filesArray = originalPath.Split(Path.AltDirectorySeparatorChar,
                              Path.DirectorySeparatorChar);
Run Code Online (Sandbox Code Playgroud)

无论文件夹数量或名称有多少,这都应该有效。


K. *_*R. 5

public static IEnumerable<string> Split(this DirectoryInfo path)
{
    if (path == null) 
        throw new ArgumentNullException("path");
    if (path.Parent != null)
        foreach(var d in Split(path.Parent))
            yield return d;
    yield return path.Name;
}
Run Code Online (Sandbox Code Playgroud)


Rol*_*and 5

受到早期答案的启发,但更简单,并且没有递归。此外,它不关心分隔符号是什么,如下Dir.Parent所示:

    /// <summary>
    /// Split a directory in its components.
    /// Input e.g: a/b/c/d.
    /// Output: d, c, b, a.
    /// </summary>
    /// <param name="Dir"></param>
    /// <returns></returns>
    public static IEnumerable<string> DirectorySplit(this DirectoryInfo Dir)
    {
        while (Dir != null)
        {
            yield return Dir.Name;
            Dir = Dir.Parent;
        }
    }
Run Code Online (Sandbox Code Playgroud)

要么将其放在static类中以创建一个不错的扩展方法,要么省略this(和static)。

按编号访问路径部分的用法示例(作为扩展方法):

    /// <summary>
    /// Return one part of the directory path.
    /// Path e.g.: a/b/c/d. PartNr=0 is a, Nr 2 = c.
    /// </summary>
    /// <param name="Dir"></param>
    /// <param name="PartNr"></param>
    /// <returns></returns>
    public static string DirectoryPart(this DirectoryInfo Dir, int PartNr)
    {
        string[] Parts = Dir.DirectorySplit().ToArray();
        int L = Parts.Length;
        return PartNr >= 0 && PartNr < L ? Parts[L - 1 - PartNr] : "";
    }
Run Code Online (Sandbox Code Playgroud)

上述两种方法现在都在我的个人库中,因此有 xml 注释。使用示例:

    DirectoryInfo DI_Data = new DirectoryInfo(@"D:\Hunter\Data\2019\w38\abc\000.d");
    label_Year.Text = DI_Data.DirectoryPart(3); // --> 2019
    label_Entry.Text = DI_Data.DirectoryPart(6);// --> 000.d
Run Code Online (Sandbox Code Playgroud)


Mar*_*son 2

快速的答案是使用 .Split('\\') 方法。

  • 如果您想将阵列与“Path.Combine”重新放在一起(如果驱动器号位于路径开头),请小心 - 这将作为“c:server\folderName1...”一起返回。 (4认同)