获取文件夹的根目录 +1

12

如何获取一个文件夹的根目录+1?

示例: 输入:C:\Level1\Level2\level3 输出应该是:

Level1

如果输入是Level1,输出应为Level1

如果输入是C:\,输出应为空字符串

是否有一个.NET函数可以处理这个问题?

Directory.GetDirectoryRoot始终返回C:\


3
没有,没有内置的函数来处理这个。 - J. Steen
9个回答

13
你可以使用 Path 类、SubstringSplit 方法来移除根目录并获取顶层文件夹。
// your directory:
string dir = @"C:\Level1\Level2\level3";     

// C:\  
string root = Path.GetPathRoot(dir); 

// Level1\Level2\level3:
string pathWithoutRoot = dir.Substring(root.Length);       

// Level1
string firstFolder = pathWithoutRoot.Split(Path.DirectorySeparatorChar).First(); 

另一种方法是使用 DirectoryInfo 类及其 Parent 属性:

DirectoryInfo directory = new DirectoryInfo(@"C:\Level1\Level2\level3");
string firstFolder = directory.Name;
while (directory.Parent != null && directory.Parent.Name != directory.Root.Name)
{
    firstFolder = directory.Parent.Name;
    directory = directory.Parent;
}

然而,我更喜欢“轻量级”的字符串方法。


5
string dir = @"C:\foo\bar\woah";
var dirSegments = dir.Split(new char[] { Path.DirectorySeparatorChar }, 
                            StringSplitOptions.RemoveEmptyEntries);
if (dirSegments.Length == 1)
{
    return string.Empty;
}
else
{
    return dirSegments[0] + Path.DirectorySeparatorChar + dirSegments[1];
}

你们太快了... :P - Conrad Clark
你应该同时包含 AltDirectorySeparatorChar - R. Martinho Fernandes
1
@R.MartinhoFernandes 为了跨平台,这是有道理的。我之前只是假设使用 Windows 环境。 - Snixtor
有趣。这意味着Mono与MSDN文档相反。http://msdn.microsoft.com/en-us/library/system.io.path.altdirectoryseparatorchar.aspx - Snixtor
因为MSDN文档是完全错误的:在Linux上,\是允许出现在文件和目录名称中的字符,它不会分隔任何内容。只有/才作为路径分隔符。按照文档所说的实现将是愚蠢的。然而,在Windows上,*两者都可以使用,并且Windows是AltDirectorySeparatorChar存在的原因。 - R. Martinho Fernandes
显示剩余4条评论

1
您可以使用目录信息类来查找,通过将以下代码段添加到方法中来实现循环查找:
string path = "C:\Level1\Level2\level3";
DirectoryInfo d = new DirectoryInfo(path);
while (d.Parent.FullName != Path.GetPathRoot(path))
{
    d = d.Parent;
}
return d.FullName;

1
您可以使用DirectoryInfowhile循环。
DirectoryInfo info = new DirectoryInfo(path);
while (info.Parent != null && info.Parent.Parent != null)
    info = info.Parent;
string result = info.FullName;

0

一种可能的解决方案,但不一定是最好的,是找到@"\"的位置,并进行一些手动处理。下面的代码没有完全测试,只是片段:

//var positions = inputString.IndexOfAny(new [] {'\'});  //Original one
//Updated, thanks to Snixtor's implementation 
var positions = inputString.IndexOfAny(new [] {Path.DirectorySeparatorChar}); 
int n=positions.Length;
if(n>=1)
{
     var pos = positions[1];  //The 2nd '\';
     return inputString.SubString(0, pos);
}
return null;

当然,这仅在我们确定要在第二个 '\' 后截断子字符串时才有效。

如果输入使用“/”,该怎么办? - R. Martinho Fernandes
新[] {'','/','...任何其他',...} - David

0
一个愉快的 Linq 一行代码:
string level1_2 = Directory.GetDirectoryRoot(path) + path.Split(Path.DirectorySeparatorChar).Skip(1).Take(1).DefaultIfEmpty("").First();

哦,我刚注意到第一个如果只是@"C:\Level1"就会失败,所以我把它移除了。 - Conrad Clark

0

为什么不直接使用System.IO.Path来获取名称呢?

MessageBox.Show(System.IO.Path.GetFileName(
    System.IO.Path.GetDirectoryName(
        System.IO.Path.GetDirectoryName(@"C:\Level1\Level2\Level3")
    )
));

这将返回一级

MessageBox.Show(System.IO.Path.GetFileName(
    System.IO.Path.GetDirectoryName(
        System.IO.Path.GetDirectoryName(@"C:\")
    )
));

这会返回一个空字符串。


这个方法如何是动态的?它期望一个三级树,使用“@C:\Level1\Level2\Level3\Level4”会返回“Level2”。 - m47730

0

不确定这是否是正确的方式,但你可以这样做:

string s = @"C:\Level1\Level2\Level3";
string foo = s.split(@"\")[1];

不确定 DirectoryInfo 对象是否可以以更简洁的方式获取此内容。

DirectoryInfo di = new DirectoryInfo(@"C:\Level1\Level2\Level3");
di.Root;

3
di.Root将返回"C:"。 - Hans Kesting
第二个选项不会像第一个那样,你应该更清楚这一点。第一个示例恰好满足了需求。 - Dr Schizo
我特别提到了“di.Root”,它只出现在第二个选项中。您的第一个选项将起作用,前提是该级别存在。如果不存在该级别,则它将失败并返回“C:\”(超出范围),而不是像OP所希望的那样返回空字符串。 - Hans Kesting

0
  var di = new System.IO.DirectoryInfo(@"C:\a\b\c");
  Func<DirectoryInfo, DirectoryInfo> root = null;
  root = (info) => info.Parent.FullName.EndsWith("\\") ? info : root(info.Parent);
  var rootName = root(di).Name; //#a

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