【问题标题】:Get last directory inside a directory ordering by name获取按名称排序的目录中的最后一个目录
【发布时间】:2016-05-11 18:56:15
【问题描述】:

我有一个包含许多文件夹的目录,名称是始终升序的数字。

例子:

1
2
3
4
5
6
7

所以,假设他们在 c:\folders\ 里面

要获取最后一个文件夹 (7),我会这样做:

string[] folders = Directory.GetDirectories("c:\folders\", "*",
                SearchOption.AllDirectories)

然后取字符串的最后一个元素。

但是这个目录有 5000 多个文件夹,所以运行 getdirectories 大约需要 1 分钟。

我为什么要这样做:

我有一个源目录和一个目标目录。我正在将源中的所有新文件夹及其内容复制到目标(是的,备份)。

这是我的代码目前所做的:

string[] directories = Directory.GetDirectories(source, "*",
                    SearchOption.AllDirectories);

foreach (string dirPath in directories)
    Directory.CreateDirectory(dirPath.Replace(source, target));

foreach (string newPath in Directory.GetFiles(source, "*.*",
    SearchOption.AllDirectories))
{
    if (!File.Exists(newPath.Replace(source, target)) && !newPath.Contains("\\Temp\\"))
    {
        File.Copy(newPath, newPath.Replace(source, target), false);
    }
}

获得最后一个文件夹后,我需要创建目录并仅将文件复制到源目录中紧随其后的文件夹中。


那么,我怎样才能更快地获得最高名称(编号)的文件夹?我可以创建一个 TXT 文件来跟踪最后插入的文件夹,但是拥有可以修改的额外文件并不是一个好方法。

啊,源包含一些带有字母的文件夹,例如 Temp。我想忽略那些文件夹,只获取名称只有数字的文件夹。

我知道这个问题听起来有点太宽泛了,我不是要求任何人做我的工作,我只是想要一个想法,经过一些研究后我没有找到合适的方法。

【问题讨论】:

    标签: c# directory .net-2.0


    【解决方案1】:

    在很多情况下,我听说Directory.EnumerateDirectories(string path) 更适合枚举。

    var path = @"C:\test";
    var highestNumberedDirectory = Directory.EnumerateDirectories(path)
                                        // Gets just the folder names without the full path
                                        .Select(d => ParseNumber(d.Split('\\').Last()))  
                                        // Orders the results by number. If you don't convert to int first then you'll start seeing some
                                        // ordering you might not expect. 1, 11, 2, 22, etc.
                                        .OrderBy(d=>d)
                                        // Gets the highest numbered result, ignoring nulls.
                                        .LastOrDefault(d => d != null);
    
    private int? ParseNumber(string potentialNumber) {
        int result;
        if (int.TryParse(potentialNumber, out result)) {
            return result;
        }
    
        return null;
    }
    

    目录结构如下:

    1
    2
    3
    10
    11
    12
    20
    21
    22
    bad
    __ok
    

    它返回 22。如果您需要完整路径,您可以简单地将其附加到原始路径

    【讨论】:

    • EnumerateDirectories 仅在 .NET 4.0 上。我忘了说我使用的是 2.0
    • 啊,这确实改变了一些事情:)
    • 我今天早上做了一些深入的研究,但仍然无法得到想要的结果。
    【解决方案2】:

    只需实现 IComparer 列表并比较路径中的最后一项 在名为 Stringcomparer 的类中

    导入 System.Collections

    Public Class Stringcomparer : 实现 IComparer(Of String) 公共函数比较(ByVal x 作为字符串,ByVal y 作为字符串)作为整数 实现 IComparer(Of String).Compare

        x = Split(x, "\")(Split(x, "\").Length - 1)
        y = Split(y, "\")(Split(y, "\").Length - 1)
        Dim ix As Int16
        Dim iy As Int16
    
        If Not Integer.TryParse(x, ix) Then
    
            ix = -1
    
        End If
    
        If Not Integer.TryParse(y, iy) Then
    
            iy = -1
    
        End If
    
    
    
        If ix > iy Then
    
    
            Return 1
    
        End If
    
        If ix < iy Then
    
    
            Return -1
    
        End If
    
        ' Return 0
    End Function
    

    结束类

    然后在代码中

        Dim FilesArray As String()
        FilesArray = Directory.GetDirectories(path)
    
    
        Dim ListofStrFile As New List(Of String)
        ListofStrFile.AddRange(FilesArray )
    
        ' take instance of Stringcomparer clases it to sort method 'method
        Dim dc As New Stringcomparer
    
    
        ListofStrFile.Sort(dc)
    

    【讨论】:

      猜你喜欢
      • 2019-01-07
      • 1970-01-01
      • 1970-01-01
      • 2015-02-15
      • 1970-01-01
      • 1970-01-01
      • 2011-08-26
      • 2011-02-11
      • 1970-01-01
      相关资源
      最近更新 更多