获取特定级别的目录

时间:2014-11-03 07:23:59

标签: c# directory subdirectory

我想通过动态路径和用户名获取原始文件夹名称,并且没有Windows默认目录

例如,

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

在这种情况下,我希望它返回"历史"对于excel.xls& record.xls。我试图使用GetFilename()方法。但它只是返回

 Spreadsheets - excel.xls
 History      - record.xls

有可能实现吗?谢谢你的帮助。

4 个答案:

答案 0 :(得分:0)

是的,documented of Path.GetFileName;

  

返回指定路径字符串的文件名和扩展名

一种解决方案可以删除您的Desktop路径,并使用Path.DirectorySeparatorChar字符进行拆分并获取第二个元素。

例如;

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

请记住,Environment.SpecialFolder.Desktop会返回当前用户桌面信息。

答案 1 :(得分:0)

没有内置的方式来做你想做的事。以下代码应该可以解决问题:

    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."));
    }

现在您可以使用它:

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"

在您的情况下,如果我没有弄错的话,您正在寻找path.GetFolderByLevel("Desktop", 1);

更新 :我修改了以前的解决方案,以便您可以使用部分或完整路径指定基本文件夹

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."));
}

现在您可以使用它:path.GetFolderByLevel(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), 1);

另一个优点是,如果嵌套文件夹具有相同的名称,您可以指定基本文件夹的唯一部分路径,以确保方法选择正确的路径。

答案 2 :(得分:0)

因此,如果我了解您想要从一组路径中找到公共基本路径? 没有任何内置函数可以做到这一点,所以你回到字符串匹配和一些LINQ给出了这个:

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

忘记添加关于我们正在做什么的评论。基本上我们遍历每个路径,并获取目录的名称,然后如果 ALL 路径包含此字符串,则它必须是公共根目录。

请注意,这将检查每条路径与其他路径的对比......并且可以进行改进。

您也可以使用一个LINQ语句:

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

答案 3 :(得分:-1)

或者这个:

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