C#: 需要从文件名路径中移除最后一个文件夹

39
我正在从数据库中获取文件路径作为文件来源。 我需要从源路径中移除最后一个文件夹,以便我可以创建新文件夹作为目标路径。
例如,源文件路径为: \\\\ServerName\\Documents\\MasterDocumentFolder\\ 我需要从该字符串中删除最后一个文件夹并获得这个路径: \\\\ServerName\\Documents\\ 这样我就可以创建一个类似于这样的文件夹: \\\\ServerName\\Documents\\NewDocumentFolder1\\ 编辑:我已更新我的示例路径,以显示为什么Path.GetDirectoryName()在此情况下不起作用。

1
你的字符串从数据库中返回时是否所有斜杠都被加倍了?或者这只是你在调试器中观察到的现象(这是正常的)? - Jon B
1
可能是从完整目录路径中删除一个目录的重复问题。 - Conrad Frix
7个回答

50

你要找的是Directory类中的GetParent()方法。

string path = @"C:\Documents\MasterDocumentFolder\";
DirectoryInfo parentDir = Directory.GetParent(path);
// or possibly
DirectoryInfo parentDir = Directory.GetParent(path.EndsWith("\\") ? path : string.Concat(path, "\\"));

// The result is available here
var myParentDir = parentDir.Parent.FullName

1
这会导致 C:\Documents\MasterDocumentFolder - Jon B
1
不,它会生成一个对象,你可以将其渲染到你所述的内容中,但它也包含Parent属性。 - Eric Herlitz
2
GetParent() 函数用于获取父目录。但是如果末尾带有 \ 符号,它会出现一些意料之外的问题。因此,你可以舍去末尾的 \ 符号,或者使用 Parent 函数来向上返回一个目录。无论哪种情况,这都不会得到正确的结果。 - Jon B
1
为 DirectoryInfo.Parent 添加了一个使用示例,这是在 .net 中解决此问题的正确方法。 - Eric Herlitz
2
@Jon 在C#中正确描述文件夹的唯一方法是在其末尾加上 \,不以反斜杠结尾的路径表示该路径指向的是一个文件。我已经使用另一种方法更新了解决方案。 - Eric Herlitz
显示剩余2条评论

12

那很丑,但是有效

string path = @"C:\Documents\MasterDocumentFolder\file.any";
var lastFolder = Path.GetDirectoryName(path);
var pathWithoutLastFolder = Path.GetDirectoryName(lastFolder);

但如果您的目录结构少于一级(驱动器根目录),那么pathWithoutLastFolder将为null,因此您需要处理它。


1
除非他有完整的路径(包括文件名),否则只需要一个单独的 Path.GetDirecotyrName() - Erik Philips
1
我已经更新了我的示例路径,以说明为什么该方法对我无效。是否有额外的步骤将 \ 转换为 \? - Mick
1
@Trikks,使用Reflector查看DirectoryInfo.Parent。你会惊讶地发现它使用了string directoryName = Path.GetDirectoryName(fullPath);。 - Sergey Berezovskiy
2
这意味着有人已经为我们编写了那段代码,不是吗? :) - Eric Herlitz
3
@Trikks 嗯,同意 Directory.GetParent(path).Parent.FullName; 看起来更好,给你点赞。 - Sergey Berezovskiy
如果路径以反斜杠结尾,则 Path.GetDirectoryName(path) 只会剥离反斜杠,而不会删除叶级目录。我使用 Path.GetDirectoryName(path.Trim().TrimEnd('\\')) 来解决这个问题。第一个 Trim 是为了确保即使后面跟着一个空格,TrimEnd 仍然可以去除末尾的反斜杠。 - Simon Elms

7

System.IO.DirectoryInfo可能是最简单的方法来实现您要求的功能。

var path = "\\\\ServerName\\Documents\\MasterDocumentFolder\\";
string newPath = new DirectoryInfo(path).Parent.CreateSubdirectory("NewDocumentFolder1").FullName;
Console.WriteLine(newPath.FullName);
//> "\\ServerName\Documents\NewDocumentFolder1\"

请注意,DirectoryInfo不需要现有或可访问的目录:
var dir = new DirectoryInfo(@"C:\Asdf\Qwer\Zxcv\Poiu\Lkj\Mn");
Console.WriteLine( dir.Exists );
//> False

但是,确保它的存在非常容易。
var dir = new DirectoryInfo(@"C:\Asdf\Qwer\Zxcv\Poiu\Lkj\Mn");
dir.Create();
Console.WriteLine( dir.Exists );
//> True

它还可以做一些很棒的事情,比如解析相对路径:

var dir = new DirectoryInfo(@"C:\Asdf\Qwer\Zxcv\Poiu\Lkj\..\..\..\Mn");
Console.WriteLine( dir.FullName );
//> C:\Asdf\Qwer\Mn

关于其他答案中的修剪和添加斜杠,请注意在处理尾随斜杠时Directory.GetParent("...\")和DirectoryInfo("...\").Parent之间行为的差异 - DirectoryInfo更一致:
Console.WriteLine( Directory.GetParent( @"C:\Temp\Test" ).FullName );
//> C:\Temp
Console.WriteLine( Directory.GetParent( @"C:\Temp\Test\" ).FullName );
//> C:\Temp\Test
Console.WriteLine( new DirectoryInfo( @"C:\Temp\Test" ).Parent.FullName );
//> C:\Temp
Console.WriteLine( new DirectoryInfo( @"C:\Temp\Test\" ).Parent.FullName );
//> C:\Temp

为了避免处理尾部斜杠,建议始终使用 Path.Combine() 来连接路径和文件名。它将正确处理包含尾部 \ 的路径:

Console.WriteLine( Path.Combine( @"C:\Temp\Test\", "Test.txt" ) );
//> C:\Temp\Test\Test.txt
Console.WriteLine( Path.Combine( @"C:\Temp\Test", "Test.txt" ) );
//> C:\Temp\Test\Test.txt
Console.WriteLine( Path.Combine( @"C:\", "Temp", "Test", "Test.txt" ) );
//> C:\Temp\Test\Test.txt

2
这应该考虑到路径既可以是文件也可以是目录。
DirectoryInfo parent = null;
if (File.Exists(path))
{
    parent = new FileInfo(path).Directory.Directory
}
if(Directory.Exists(path))
{
    parent = new DirectoryInfo(path).Directory;
}

2
你的表达式可能需要包含 DirectoryInfo.Exists 吗? - Eric Herlitz

1

你尝试过按 "\" 分割字符串,然后通过连接除最后一个元素外的每个元素来重构新路径吗?

你还需要考虑原始路径在根目录的情况,以及是否以反斜杠结尾。


4
由于这个原因,.NET包括System.IO命名空间和Path对象。 - Jason Meckley

0
使用这种方法,您可以通过dirPath(如果目录不存在)创建目录,并根据需要从filePath创建目录。
private void CreateDirIfNotExist(string dirPath, bool removeFilename = false)
{
    if (removeFilename)
        dirPath = Directory.GetParent(dirPath).FullName;

    if (!Directory.Exists(dirPath))
        Directory.CreateDirectory(dirPath);
}

-1

在VB中:

Dim MyNewPath As String = StrReverse(Strings.Split(StrReverse(MyPath), "\", 2)(1))

这适用于根目录,例如C:\MyPath,但对于裸文件夹(没有验证)则失败。

显然,如果有文件附加,则需要进行不同的处理。


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