简体   繁体   中英

C# Get Directory Names

Here is some code i have been trying to use to get just directory names - However its returning the full filepath rather than all the directories in SUBDIR2. I can do a split string but the length of the Dir changes

public void Getdire1(string Servername)
{
    string[] dirs = Directory.GetDirectories("\\\\" 
        + Servername 
        + "\\E$\\SUBDIR1\\SUBDIR2\\");

    foreach (string item in dirs)
    {
        MessageBox.Show(item);
    }
}

Can anyone help please

Use Path.GetDirectoryName(string)

https://docs.microsoft.com/en-us/dotnet/api/system.io.path.getdirectoryname?view=net-5.0

public void Getdire1(string Servername) 
{
    string[] dirs = Directory.GetDirectories("\\\\" + Servername + "\\E$\\SUBDIR1\\SUBDIR2\\");
    

    foreach (string item in dirs)
    {
        MessageBox.Show(Path.GetDirectoryName(item));
    }
}

See the samples in the docs to make sure you get the desired output, be for example mindful about C:\mydir and C:\mydir\ .

EDIT: :

In that case you can use Path.GetFileName(string) but this only works if your path does not end with \ , eg C:\MyDir works but C:\MyDir\ won't.

You can use String.TrimEnd(string) for this like so: "C:\\mydir\\".TrimEnd('\\') . I think Path.GetFileName("C:\\mydir\\".TrimEnd(Path.DirectorySeparatorChar)) would work.

Or even this: Path.GetFileName(Path.GetDirectoryName("C:\\mydir\\")) but be careful, C:\DirA\DirB\ will result in DirB but C:\DirA\DirB will result in DirA !

EDIT2: The answer from @Stefano Cavion also seems sensible, although if I just wanted the name I personally would not like to instantiate a whole class just to get the name of a directory from some string. Thats just taste. For funsies i've decided to run a small benchmark to see if there are better choices performance wise, and funnily enough the .TrimEnd() solution seems to be the fastest in a way. Of course caring about performance on this level seems a bit too much unless you're doing something very special so take this with a grain of salt...

BenchmarkDotNet=v0.13.0, OS=Windows 10.0.17134.677 (1803/April2018Update/Redstone4)
Intel Core i7-7700HQ CPU 2.80GHz (Kaby Lake), 2 CPU, 7 logical and 7 physical cores
.NET SDK=5.0.202
  [Host]     : .NET Core 3.1.14 (CoreCLR 4.700.21.16201, CoreFX 4.700.21.16208), X64 RyuJIT  [AttachedDebugger]
  DefaultJob : .NET Core 3.1.14 (CoreCLR 4.700.21.16201, CoreFX 4.700.21.16208), X64 RyuJIT
Method Mean Error StdDev
UseTrimEnd 462.2 ns 17.73 ns 50.59 ns
UseGetDirectoryName 621.2 ns 18.26 ns 53.56 ns
UseGetDirectoryInfo 1,397.8 ns 26.71 ns 65.51 ns

The environment and .net core version would also give some variance, as well as me using the computer whilst the test was running.

Code:

public class PathBenchMark
{
    public List<string> Paths = new List<string>(new[] { @"C:\MyDir", @"C:\MyDir\", @"C:\A\B", @"C:\A\B\" });

    [Benchmark]
    public List<string> UseTrimEnd() => Paths.Select(c => Path.GetFileName(c.TrimEnd(Path.DirectorySeparatorChar))).ToList();
    [Benchmark]
    public List<string> UseGetDirectoryName() => Paths.Select(c => Path.GetFileName(Path.GetDirectoryName(c))).ToList();
    [Benchmark]
    public List<string> UseGetDirectoryInfo() => Paths.Select(c => new DirectoryInfo(c).Name).ToList();

}

class Program
{
    public static void Main()
    {
        BenchmarkRunner.Run<PathBenchMark>();
    }
}

EDIT3: I've ran another benchmark by using new DirectoryInfo(string).GetDirectories(string) . I also edited the UseGetDirectoryName case, because Directory.GetDirectories() returns the full path without trailing \ which would return the wrong directory... Ie i'm going with DirectoryInfo or with TrimEnd() from now on since i don't wanna be making the same mistake.


BenchmarkDotNet=v0.13.0, OS=Windows 10.0.17134.677 (1803/April2018Update/Redstone4)
Intel Core i7-7700HQ CPU 2.80GHz (Kaby Lake), 2 CPU, 7 logical and 7 physical cores
.NET SDK=5.0.202
  [Host]     : .NET Core 3.1.14 (CoreCLR 4.700.21.16201, CoreFX 4.700.21.16208), X64 RyuJIT
  DefaultJob : .NET Core 3.1.14 (CoreCLR 4.700.21.16201, CoreFX 4.700.21.16208), X64 RyuJIT


Method Mean Error StdDev
UseTrimEnd 49.57 μs 0.976 μs 1.085 μs
UseGetDirectoryName 49.30 μs 0.703 μs 0.624 μs
UseNewDirectoryInfo 51.82 μs 1.021 μs 1.362 μs
UseDirectoryInfoGetDirectories 49.78 μs 0.789 μs 0.877 μs
public class PathBenchMark
{
    private const string RootPath = @"C:\Program Files\dotnet\";
    public List<string> Paths => Directory.GetDirectories(RootPath, "*", SearchOption.AllDirectories).ToList();

    [Benchmark]
    public List<string> UseTrimEnd() => Paths.Select(c => Path.GetFileName(c.TrimEnd(Path.DirectorySeparatorChar))).ToList();
    
    [Benchmark]
    public List<string> UseGetDirectoryName() => Paths.Select(c => Path.EndsInDirectorySeparator(c) ? Path.GetFileName(Path.GetDirectoryName(c)) : Path.GetFileName(c) ).ToList();
    [Benchmark]
    public List<string> UseNewDirectoryInfo() => Paths.Select(c => new DirectoryInfo(c).Name).ToList();

    [Benchmark]
    public List<string> UseDirectoryInfoGetDirectories() => new DirectoryInfo(RootPath).GetDirectories("*", SearchOption.AllDirectories).Select(c => c.Name).ToList();
    
}

class Program
{
    public static void Main()
    {        
        BenchmarkRunner.Run<PathBenchMark>();
    }
}

You can use the DirectoryInfo class for retreive all the info you need, take a look to Microsoft documentation

        string[] dirs = Directory.GetDirectories("\\\\" + Servername + "\\E$\\SUBDIR1\\SUBDIR2\\");
        foreach(var dir in dirs)
        {
            var dirInfo = new DirectoryInfo(dir);
            MessageBox.Show(dinfo.Name);     //This will show only the directory name
            MessageBox.Show(dinfo.FullName); //This will show the complete path of the directory
        }

this should work for you.

    public void Getdire1(string Servername)
    {
        string[] dirs = Directory.GetDirectories("\\\\" + Servername + "\\E$\\SUBDIR1\\SUBDIR2\\");
    
    
        foreach (string item in dirs)
        {
            System.Windows.Forms.MessageBox.Show(Path.GetFileName(item));
        }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM