Подтвердить что ты не робот

Как извлечь каждое имя папки из пути?

Мой путь \\server\folderName1\another name\something\another folder\

Как извлечь каждое имя папки в строку, если я не знаю, сколько папок есть в пути, и я не знаю имена папок?

Большое спасибо

4b9b3361

Ответ 1

string mypath = @"..\folder1\folder2\folder2";
string[] directories = mypath.Split(Path.DirectorySeparatorChar);

Изменить: Это возвращает каждую отдельную папку в массиве каталогов. Вы можете получить количество возвращенных папок следующим образом:

int folderCount = directories.Length;

Ответ 2

Это хорошо в общем случае:

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 вместо @"\/" в приведенном выше коде. Лично я считаю это слишком многословным и, скорее всего, не сделаю этого.

Ответ 3

Поймите, это старый пост, но я натолкнулся на него - в конце концов я решил использовать функцию ниже, поскольку он сортировал то, что я делал в то время, лучше любого из вышеперечисленных:

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

Я вижу ваш метод 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;
}

На пути 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

Ответ 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;
}

Ответ 6

    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    /// <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;
    }

Ответ 7

Быстрый ответ заключается в использовании метода .Split('\\').

Ответ 8

Возможно, вызовите Directory.GetParent в цикле? Это, если вы хотите полный путь к каждому каталогу, а не только имена каталогов.

Ответ 9

Вдохновлен более ранними ответами, но проще и без рекурсии. Также не имеет значения, что такое символ разделения, поскольку 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, чтобы создать хороший метод расширения, либо просто пропустите thisstatic).

Пример использования (как метод расширения) для доступа к частям пути по номеру:

    /// <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

Ответ 10

Существует несколько способов представления пути к файлу. Вы должны использовать класс 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

Или, если вам нужно что-то делать с каждой папкой, посмотрите класс System.IO.DirectoryInfo. Он также имеет свойство Parent, которое позволяет вам перейти к родительскому каталогу.

Ответ 12

Я написал следующий метод, который работает для меня.

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 = new DirectoryInfo (@path); DirectoryInfo [] folderList = directories.GetDirectories();

Ответ 13

DirectoryInfo objDir = new DirectoryInfo(direcotryPath);
DirectoryInfo [] directoryNames =  objDir.GetDirectories("*.*", SearchOption.AllDirectories);

Это даст вам все каталоги и подкаталоги.

Ответ 14

Я добавляю к ответу Мэтта Брунелла.

            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\другое имя

"\ server\folderName1\другое имя \something"

"\ server\folderName1\другое имя\something\другая папка \"

(или отсортируйте полученный результат по строке. Длина каждого значения.

Ответ 15

Здесь приведена модификация ответа Волка, которая оставляет корень и исправляет то, что, казалось, было парочкой ошибок. Я использовал его для создания панировочных сухарей, и я не хотел, чтобы отображался корень.

это расширение типа 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;
}

Ответ 16

Я просто кодировал это, так как я не нашел ни одного уже встроенного в С#.

/// <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;
}