我的路径是\\server\folderName1\another name\something\another folder\
如果我不知道路径中有多少文件夹而且我不知道文件夹名称,如何将每个文件夹名称提取为字符串?
非常感谢
答案 0 :(得分:88)
string mypath = @"..\folder1\folder2\folder2";
string[] directories = mypath.Split(Path.DirectorySeparatorChar);
编辑: 这将返回目录数组中的每个单独的文件夹。您可以获得这样返回的文件夹数:
int folderCount = directories.Length;
答案 1 :(得分:26)
这在一般情况下是好的:
yourPath.Split(@"\/", StringSplitOptions.RemoveEmptyEntries)
如果路径本身以(后退)斜杠结尾(例如“\ 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
}
我相信这涵盖了所有基础,而不是太迂腐。它将返回string[]
,您可以使用foreach
进行迭代,以便依次获取每个目录。
如果要使用常量而不是@"\/"
魔术字符串,则需要使用
var separators = new char[] {
Path.DirectorySeparatorChar,
Path.AltDirectorySeparatorChar
};
然后在上面的代码中使用separators
代替@"\/"
。就个人而言,我觉得这个问题太冗长了,很可能不会这样做。
答案 2 :(得分:9)
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;
}
在路径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;
}
将返回
c:\
folder1
folder2
folder3
答案 3 :(得分: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;
}
答案 4 :(得分:4)
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;
}
答案 5 :(得分:4)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/// <summary>
/// Use to emulate the C lib function _splitpath()
/// </summary>
/// <param name="path">The path to split</param>
/// <param name="rootpath">optional root if a relative path</param>
/// <returns>the folders in the path.
/// Item 0 is drive letter with ':'
/// If path is UNC path then item 0 is "\\"
/// </returns>
/// <example>
/// string p1 = @"c:\p1\p2\p3\p4";
/// string[] ap1 = p1.SplitPath();
/// // ap1 = {"c:", "p1", "p2", "p3", "p4"}
/// string p2 = @"\\server\p2\p3\p4";
/// string[] ap2 = p2.SplitPath();
/// // ap2 = {@"\\", "server", "p2", "p3", "p4"}
/// string p3 = @"..\p3\p4";
/// string root3 = @"c:\p1\p2\";
/// string[] ap3 = p1.SplitPath(root3);
/// // ap3 = {"c:", "p1", "p3", "p4"}
/// </example>
public static string[] SplitPath(this string path, string rootpath = "")
{
string drive;
string[] astr;
path = Path.GetFullPath(Path.Combine(rootpath, path));
if (path[1] == ':')
{
drive = path.Substring(0, 2);
string newpath = path.Substring(2);
astr = newpath.Split(new[] { Path.DirectorySeparatorChar }
, StringSplitOptions.RemoveEmptyEntries);
}
else
{
drive = @"\\";
astr = path.Split(new[] { Path.DirectorySeparatorChar }
, StringSplitOptions.RemoveEmptyEntries);
}
string[] splitPath = new string[astr.Length + 1];
splitPath[0] = drive;
astr.CopyTo(splitPath, 1);
return splitPath;
}
答案 6 :(得分:3)
快速回答是使用.Split('\\')方法。
答案 7 :(得分:2)
也许在循环中调用Directory.GetParent?如果你想要每个目录的完整路径而不仅仅是目录名。
答案 8 :(得分:2)
受到早期答案的启发,但更简单,而且没有递归。另外,它也不在乎分隔符号是什么,因为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;
}
}
要么将其放在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] : "";
}
以上两种方法现在都在我的个人库中,因此是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
答案 9 :(得分:1)
我用它来循环文件夹 ftp 服务器
public List<string> CreateMultiDirectory(string remoteFile)
var separators = new char[] { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar };
string[] directory = Path.GetDirectoryName(remoteFile).Split(separators);
var path = new List<string>();
var folder = string.Empty;
foreach (var item in directory)
{
folder += $@"{item}\";
path.Add(folder);
}
return path;
答案 10 :(得分:1)
有几种方法可以表示文件路径。您应该使用System.IO.Path
类来获取操作系统的分隔符,因为它可能因UNIX和Windows而异。此外,大多数(或所有,如果我没有记错).NET库接受'\'或'/'作为路径分隔符,无论操作系统如何。出于这个原因,我将使用Path类来拆分路径。尝试以下内容:
string originalPath = "\\server\\folderName1\\another\ name\\something\\another folder\\";
string[] filesArray = originalPath.Split(Path.AltDirectorySeparatorChar,
Path.DirectorySeparatorChar);
无论文件夹数量或名称如何,这都应该有效。
答案 11 :(得分:0)
我正在补充Matt Brunell的答案。
string[] directories = myStringWithLotsOfFolders.Split(Path.DirectorySeparatorChar);
string previousEntry = string.Empty;
if (null != directories)
{
foreach (string direc in directories)
{
string newEntry = previousEntry + Path.DirectorySeparatorChar + direc;
if (!string.IsNullOrEmpty(newEntry))
{
if (!newEntry.Equals(Convert.ToString(Path.DirectorySeparatorChar), StringComparison.OrdinalIgnoreCase))
{
Console.WriteLine(newEntry);
previousEntry = newEntry;
}
}
}
}
这应该给你:
“\服务器”
“\服务器\ folderName1”
“\ server \ folderName1 \ another name”
“\ server \ folderName1 \ another name \ something”
“\ server \ folderName1 \ another name \ something \ another folder \”
(或按照每个值的string.Length对结果集合进行排序。
答案 12 :(得分:0)
DirectoryInfo objDir = new DirectoryInfo(direcotryPath);
DirectoryInfo [] directoryNames = objDir.GetDirectories("*.*", SearchOption.AllDirectories);
这将为您提供所有目录和子目录。
答案 13 :(得分:0)
我写了以下方法,对我有用。
protected bool isDirectoryFound(string path, string pattern)
{
bool success = false;
DirectoryInfo directories = new DirectoryInfo(@path);
DirectoryInfo[] folderList = directories.GetDirectories();
Regex rx = new Regex(pattern);
foreach (DirectoryInfo di in folderList)
{
if (rx.IsMatch(di.Name))
{
success = true;
break;
}
}
return success;
}
与您的问题最相关的行是:
DirectoryInfo目录=新的DirectoryInfo(@path); DirectoryInfo [] folderList = directories.GetDirectories();
答案 14 :(得分:0)
这里修改了沃尔夫的答案,遗漏了根并解决了几个错误。我用它来生成面包屑,我不想要显示根。
这是DirectoryInfo
类型的扩展名。
public static List<DirectoryInfo> PathParts(this DirectoryInfo source, string rootPath)
{
if (source == null) return null;
DirectoryInfo root = new DirectoryInfo(rootPath);
var pathParts = new List<DirectoryInfo>();
var di = source;
while (di != null && di.FullName != root.FullName)
{
pathParts.Add(di);
di = di.Parent;
}
pathParts.Reverse();
return pathParts;
}
答案 15 :(得分:0)
我刚刚编写了此代码,因为我发现C#中尚未内置任何代码。
/// <summary>
/// get the directory path segments.
/// </summary>
/// <param name="directoryPath">the directory path.</param>
/// <returns>a IEnumerable<string> containing the get directory path segments.</returns>
public IEnumerable<string> GetDirectoryPathSegments(string directoryPath)
{
if (string.IsNullOrEmpty(directoryPath))
{ throw new Exception($"Invalid Directory: {directoryPath ?? "null"}"); }
var currentNode = new System.IO.DirectoryInfo(directoryPath);
var targetRootNode = currentNode.Root;
if (targetRootNode == null) return new string[] { currentNode.Name };
var directorySegments = new List<string>();
while (string.Compare(targetRootNode.FullName, currentNode.FullName, StringComparison.InvariantCultureIgnoreCase) != 0)
{
directorySegments.Insert(0, currentNode.Name);
currentNode = currentNode.Parent;
}
directorySegments.Insert(0, currentNode.Name);
return directorySegments;
}
答案 16 :(得分:0)
或者,如果您需要对每个文件夹执行某些操作,请查看System.IO.DirectoryInfo类。它还有一个Parent属性,允许您导航到父目录。