web-dev-qa-db-fra.com

Comment extraire chaque nom de dossier d'un chemin?

Mon chemin est \\server\folderName1\another name\something\another folder\

Comment extraire chaque nom de dossier dans une chaîne si je ne sais pas combien de dossiers il y a dans le chemin et si je ne connais pas les noms de dossier?

Merci beaucoup

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

Edit: Ceci renvoie chaque dossier individuel dans le tableau de répertoires. Vous pouvez obtenir le nombre de dossiers retournés comme ceci:

int folderCount = directories.Length;
87
Matt Brunell

C'est bien dans le cas général:

yourPath.Split(@"\/", StringSplitOptions.RemoveEmptyEntries)

Il n'y a pas d'élément vide dans le tableau retourné si le chemin d'accès se termine par une barre oblique inverse (par exemple, "\ foo\bar \"). Cependant, vous devrez être sûr que yourPath est vraiment un répertoire et non un fichier. Vous pouvez trouver ce que c'est et compenser s'il s'agit d'un fichier comme celui-ci:

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
}

Je crois que cela couvre toutes les bases sans être trop pédant. Il retournera un string[] que vous pouvez parcourir avec foreach pour obtenir chaque répertoire à tour de rôle.

Si vous souhaitez utiliser des constantes au lieu de la chaîne magique @"\/", vous devez utiliser

var separators = new char[] {
  Path.DirectorySeparatorChar,  
  Path.AltDirectorySeparatorChar  
};

puis utilisez separators au lieu de @"\/" dans le code ci-dessus. Personnellement, je trouve cela trop verbeux et ne le ferais probablement pas.

25
Jon

Je vois votre méthodeWolf5370 et je vous relève.

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

Sur le chemin c:\folder1\folder2\folder3 ceci retourne

c:\

c:\folder1

c:\folder1\folder2

c:\folder1\folder2\folder3

Dans cet ordre

OR

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

reviendra

c:\

folder1

folder2

folder3

9
Kelly Elton

Réalisez que ceci est un ancien post, mais je l’ai trouvé - j’ai finalement décidé de la fonction ci-dessous, car elle triait ce que je faisais à l’époque mieux que tout ce qui précède:

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;
}
9
Wolf5370
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;
}
4
K. R.
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    /// <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;
    }
4
Michael Fitzpatrick

La réponse rapide consiste à utiliser la méthode .Split ('\\').

3
Mark A Johnson

Peut-être appeler Directory.GetParent dans une boucle? C'est si vous voulez le chemin complet de chaque répertoire et pas seulement les noms de répertoire.

2
Brian

Un chemin de fichier peut être représenté de plusieurs manières. Vous devez utiliser la classe System.IO.Path pour obtenir les séparateurs du système d'exploitation, car elle peut varier entre UNIX et Windows. De plus, la plupart des bibliothèques .NET (ou toutes si je ne me trompe pas) acceptent un '\' ou un '/' comme séparateur de chemin, quel que soit le système d'exploitation. Pour cette raison, j'utiliserais la classe Path pour diviser vos chemins. Essayez quelque chose comme ce qui suit:

string originalPath = "\\server\\folderName1\\another\ name\\something\\another folder\\";
string[] filesArray = originalPath.Split(Path.AltDirectorySeparatorChar,
                              Path.DirectorySeparatorChar);

Cela devrait fonctionner indépendamment du nombre de dossiers ou des noms.

1
Dan Herbert

J'ai écrit la méthode suivante qui fonctionne pour moi. 

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

Les lignes les plus pertinentes pour votre question étant:

DirectoryInfo Directories = new DirectoryInfo (@path); DirectoryInfo [] folderList = Directories.GetDirectories ();

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

Cela vous donnera tous les répertoires et sous-répertoires.

0
Navish Rampal

Ou, si vous avez besoin de faire quelque chose avec chaque dossier, consultez la classe System.IO.DirectoryInfo. Il possède également une propriété Parent qui vous permet de naviguer dans le répertoire parent.

0
M4N

Je viens de coder ceci car je n'en ai trouvé aucun déjà construit en 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;
}
0
hmadrigal

Voici une modification de la réponse de Wolf qui laisse de côté la racine et corrige ce qui semblait être quelques bugs. Je l'ai utilisé pour générer une chapelure et je ne voulais pas que la racine soit affichée.

c'est une extension du type 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;
}
0
toddmo

J'ajoute à la réponse de 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;
                        }
                    }
                }
            }

Cela devrait vous donner:

"\serveur"

"\ server\folderName1"

"\ serveur\nomDossier1\autre nom"

"\ serveur\nomDossier1\autre nom\quelque chose"

"\ serveur\nomDossier1\autre nom\quelque chose\autre dossier \"

(ou triez votre collection résultante par la chaîne.Longueur de chaque valeur.

0
granadaCoder