Get specific level of directory

一笑奈何 提交于 2021-02-10 04:36:41

问题


i would like to get the original folder name by dynamic path and username, and without Windows default directory

For example,

 C:\Users\dynamic user\Desktop\History\2014-11-03\Spreadsheets\excel.xls
 C:\Users\dynamic user\Desktop\History\record.xls

In this case, i want it to return "History" for excel.xls & record.xls. I tried to use GetFilename() method. But it just returns

 Spreadsheets - excel.xls
 History      - record.xls

Is it possible to achieve? Thanks for your help.


回答1:


Yes, as documented of Path.GetFileName;

Returns the file name and extension of the specified path string.

One solution can be delete your Desktop path and split with Path.DirectorySeparatorChar character and gets second element.

For example;

string path = @"C:\Users\dynamic user\Desktop\History\2014-11-03\Spreadsheets\excel.xls";
var desktop = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);

path = path.Replace(desktop, "");
var history = path.Split(Path.DirectorySeparatorChar)[1];
Console.WriteLine(history); // History

Remember, Environment.SpecialFolder.Desktop returns current user desktop information.




回答2:


So if I've understood you want to find the common base path from a set of paths? There isn't any built in function to do this, so your back to string matching and some LINQ gives this:

        static void Main(string[] args)
    {
        List<string> paths = new List<string>()
            {
                @"C:\Users\dynamic user\Desktop\History\2014-11-03\Spreadsheets\excel.xls"
                ,@"C:\Users\dynamic user\Desktop\History\record.xls"
                ,@"C:\Users\dynamic user\Desktop\History\2014-11-23\Spreadsheets\excel.xls"
                ,@"C:\Users\dynamic user\Desktop\History\2014-11-03\excel.xls"
            };

        Console.WriteLine("The common base path of:");
        paths.ForEach(f => Console.WriteLine(f));
        Console.WriteLine("is");
        Console.WriteLine(FindBasePath(paths));

        Console.ReadLine();
    }

    static string FindBasePath(List<string> paths)
    {
        string basePath = String.Empty;

        foreach (string path in paths)
        {
            string dirName = Path.GetDirectoryName(path);

            if (paths.All(f => Path.GetDirectoryName(f).Contains(dirName)))
                return basePath = dirName;
        }

        return basePath;
    }

Forgot to add comment as to what we're doing. Basically we loop over every path, and get the name of the directory, then if ALL the paths contains this string, it must be the common root directory.

Note this will check every path against every other path...and could be improved.

You could also do it one LINQ statement:

paths.Select(f => Path.GetDirectoryName(f)
     .Select(f => paths.All(g => g.Contains(f)) ? f : "")
     .Where(f => !String.IsNullOrEmpty(f))
     .First()



回答3:


There is no in-built way of doing what you want. The following code should do the trick:

    public static string GetFolderByLevel(this string path, string baseFolderName, int level)
    {
        if (path == null)
            throw new ArgumentNullException("path");

        if (baseFolderName == null)
            throw new ArgumentNullException("baseFolderName");

        var pathWithoutFile = Path.GetDirectoryName(path);

        var folders = pathWithoutFile.ToString().Split(Path.DirectorySeparatorChar);
        int baseFolderLevel = -1;

        for (int i = 0; i < folders.Length; ++i)
        {
            if (string.Compare(folders[i], baseFolderName, true) == 0)
            {
                baseFolderLevel = i;
                break;
            }
        }

        if (baseFolderLevel == -1)
            throw new ArgumentException(string.Format("Folder '{0}' could not be found in specified path: {1}", baseFolderName, path), "baseFolderName");

        int index = baseFolderLevel + level;

        if (-1 < index && index < folders.Length)
        {
            return folders[index];
        }
        else
            throw new ArgumentOutOfRangeException(string.Format("Specified level is out of range."));
    }

Now you can use it like:

string path = @"C:\Users\dynamic user\Desktop\History\Peter\record.xls";

path.GetFolderByLevel("Desktop", -2); //returns "Users"
path.GetFolderByLevel("History", 0); //returns "History"
path.GetFolderByLevel("Desktop", 1); //returns "History"

In your case, if I'm not mistaken, your are looking for path.GetFolderByLevel("Desktop", 1);

UPDATE: I've modified the previous solution so that you can specify the base folder with a partial or full path:

public static string GetFolderByLevel(this string path, string baseFolderPath, int level)
{
    if (path == null)
        throw new ArgumentNullException("path");

    if (baseFolderPath == null)
        throw new ArgumentNullException("baseFolderName");

    var pathFolders = path.Split(new char[] {Path.DirectorySeparatorChar}, StringSplitOptions.RemoveEmptyEntries);
    var basePathFolders = baseFolderPath.Split(new char[] { Path.DirectorySeparatorChar }, StringSplitOptions.RemoveEmptyEntries);

    int baseFolderIndex = -1;
    int folderCounter = 0;

    for (int i = 0; i < pathFolders.Length; ++i)
    {
        if (string.Compare(pathFolders[i], basePathFolders[folderCounter], true) == 0)
        {
            if (++folderCounter == basePathFolders.Length)
            {
                baseFolderIndex = i;
                break;
            }
        }
        else
        {
            folderCounter = 0;
        }
    }

    if (baseFolderIndex < 0)
       throw new ArgumentException(string.Format("Folder '{0}' could not be found in specified path: {1}", baseFolderPath, path), "baseFolderName");

    int index = baseFolderIndex + level;

    if (-1 < index && index < pathFolders.Length)
    {
        return pathFolders[index];
    }
    else
        throw new ArgumentOutOfRangeException(string.Format("Specified level is out of range."));
}

Now you could use it like: path.GetFolderByLevel(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), 1);

An additional advantage would be in case of having nested folders with the same name, you can specify the unique partial path of the base folder to make sure the method picks the right one.




回答4:


Or this:

 var dir_path = Path.GetDirectoryName(@"C:\your\path\with\file.ext");
 var dir_name = new DirectoryInfo(dir_path).Name;


来源:https://stackoverflow.com/questions/26709568/get-specific-level-of-directory

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!