Поиск родительского каталога в DirectoryInfo - PullRequest
1 голос
/ 14 марта 2019

Есть ли способ поиска определенного родительского каталога?

Я знаю, что могу получить родительский каталог для этого

Directory.GetParent(Directory.GetCurrentDirectory()).FullName

Но это возвращает непосредственного родителя, есть ли способ поиска определенного родителя в иерархии каталогов пути?

EDIT

Я пытаюсь достичь, скажем, если у меня есть текущий каталог, как это

C:/Project/Source/Dev/Database

Итак, я хочу добраться до каталога Source Я знаю, что могу достичь этого, дважды вызвав метод GetParent, но я не думаю, что это правильный способ сделать это, потому что, если в будущем мой файл изменится, текущая директория и она пойдет дальше вниз. Поэтому я хочу получить полный способ доказательства, где я могу непосредственно найти путь к каталогу Source независимо от того, насколько глубоко я нахожусь в текущем каталоге, потому что это точно, что я буду внутри каталога Source

Так что-то вроде

FindParent('Source')

Ответы [ 4 ]

1 голос
/ 14 марта 2019

Directory.GetCurrentDirectory() возвращает строку, представляющую полный абсолютный путь к текущему каталогу.

Если вы хотите получить путь к определенному родительскому каталогу, вы можете просто использовать substring:

var path = Directory.GetCurrentDirectory(); // Suppose C:/Project/Source/Dev/Database
var sourceDir = new string[] {Path.DirectorySeparatorChar + "Source" + Path.DirectorySeparatorChar,
                           Path.AltDirectorySeparatorChar + "Source" + Path.AltDirectorySeparatorChar};

var sourcePath = path.IndexOf(sourceDir[0], StringComparison.OrdinalIgnoreCase) > -1 ?
    path.Substring(0, path.IndexOf(sourceDir[0]) + sourceDir[0].Length) :
    path.IndexOf(sourceDir[1], StringComparison.OrdinalIgnoreCase) > -1 ? 
        path.Substring(0, path.IndexOf(sourceDir[1]) + sourceDir[1].Length) : 
        null;

Я использовал Path.DirectorySeparatorChar и Path.AltDirectorySeparatorChar в качестве разделителей, поэтомучто код будет работать одинаково на каждой платформе.

1 голос
/ 14 марта 2019

Вы можете попробовать что-то вроде этого (for loop):

private static IEnumerable<String> ParentDirectories(string directory = null) {
  for (string dir = null == directory ? Directory.GetCurrentDirectory() : directory;
       dir != null;
       dir = Directory.GetParent(dir)?.FullName)
    yield return dir;
}

Демо:

var demo = string.Join(Environment.NewLine, 
  ParentDirectories(@"C:/Project/Source/Dev/Database"));

Console.Write(demo);

Результат:

C:/Project/Source/Dev/Database // initial directory
C:\Project\Source\Dev          // and its all parents
C:\Project\Source
C:\Project
C:\

Если вы не хотите включать сам каталог, добавьте .Skip(1):

var demo = string.Join(Environment.NewLine, 
  ParentDirectories(@"C:/Project/Source/Dev/Database").Skip(1));

Наконец, если вы хотите найти родительский каталог, который заканчивается на Source:

string dirName = "Source";

string myParent = ParentDirectories(@"C:/Project/Source/Dev/Database")
  .FirstOrDefault(dir => string.Equals(
     dirName,
     new DirectoryInfo(dir).Name, 
     StringComparison.OrdinalIgnoreCase));

Console.Write(myParent); 

Результат:

C:\Project\Source
0 голосов
/ 14 марта 2019

На самом деле я думал, что существует уже существующий способ или функция, но если мне придется написать это самому, тогда это решение, которое я написал, сработало для меня

    private static string GetParent(string directoryPath, string parent)
    {
        DirectoryInfo directory = new DirectoryInfo(directoryPath);
        while (directory.Parent!=null)
        {
            if (directory.Parent.Name.ToLower() == parent.ToLower())
            {
                return directory.Parent.FullName;
            }

            directory = directory.Parent;
        }

        return null;
    }
0 голосов
/ 14 марта 2019

Два варианта без дополнительной информации о вашей ситуации:

  1. DirectoryInfo.GetDirectories даст вам все дочерние каталоги Current каталог, поэтому вам нужно будет переключить ваш текущий в корень + 1

  2. System.IO.Path.Combine (myPath, "..") , который будет действоватьбольше похоже на cd ..

...