【问题标题】:Sorting Directory.GetFiles()排序 Directory.GetFiles()
【发布时间】:2010-09-08 08:18:22
【问题描述】:

System.IO.Directory.GetFiles() 返回一个string[]。返回值的默认排序顺序是什么?我是按名字假设的,但如果是这样的话,当前的文化对它有多大影响?您可以将其更改为创建日期之类的内容吗?

更新: MSDN 指出 .Net 3.5 不能保证排序顺序,但 2.0 版本的页面根本没有说明任何内容,而且这两个页面都不会帮助您按事物排序比如创建或修改时间。一旦有了数组(它只包含字符串),该信息就会丢失。我可以构建一个比较器来检查它获取的每个文件,但这意味着当 .GetFiles() 方法可能已经这样做时重复访问文件系统。看起来效率很低。

【问题讨论】:

标签: .net .net-2.0


【解决方案1】:

更简洁的 VB.Net 版本...非常好。谢谢你。 要逆序遍历列表,添加reverse方法...

For Each fi As IO.FileInfo In filePaths.reverse
  ' Do whatever you wish here
Next

【讨论】:

    【解决方案2】:

    Dim Files() As String
    Files = System.IO.Directory.GetFiles("C:\")
    Array.Sort(Files)
    

    【讨论】:

      【解决方案3】:

      一个更简洁的VB.Net版本,如果有人感兴趣的话

      Dim filePaths As Linq.IOrderedEnumerable(Of IO.FileInfo) = _
        New DirectoryInfo("c:\temp").GetFiles() _
         .OrderBy(Function(f As FileInfo) f.CreationTime)
      For Each fi As IO.FileInfo In filePaths
        ' Do whatever you wish here
      Next
      

      【讨论】:

        【解决方案4】:

        这是我使用的 VB.Net 解决方案。

        首先创建一个类来比较日期:

        Private Class DateComparer
            Implements System.Collections.IComparer
        
            Public Function Compare(ByVal info1 As Object, ByVal info2 As Object) As Integer Implements System.Collections.IComparer.Compare
                Dim FileInfo1 As System.IO.FileInfo = DirectCast(info1, System.IO.FileInfo)
                Dim FileInfo2 As System.IO.FileInfo = DirectCast(info2, System.IO.FileInfo)
        
                Dim Date1 As DateTime = FileInfo1.CreationTime
                Dim Date2 As DateTime = FileInfo2.CreationTime
        
                If Date1 > Date2 Then Return 1
                If Date1 < Date2 Then Return -1
                Return 0
            End Function
        End Class
        

        然后在对数组进行排序时使用比较器:

        Dim DirectoryInfo As New System.IO.DirectoryInfo("C:\")
        Dim Files() As System.IO.FileInfo = DirectoryInfo.GetFiles()
        Dim comparer As IComparer = New DateComparer()
        Array.Sort(Files, comparer)
        

        【讨论】:

        • 我已经编辑了示例代码,因为 Array.Sort 需要 DateComparer 的实例,或者我们得到“DateComparer 是一种类型,不能用作表达式”错误。感谢您提供的代码,因为它几乎可以使用了。
        【解决方案5】:

        如果您对文件的属性(例如 CreationTime)感兴趣,那么使用 System.IO.DirectoryInfo.GetFileSystemInfos() 会更有意义。 然后,您可以使用 System.Linq 中的一种扩展方法对它们进行排序,例如:

        DirectoryInfo di = new DirectoryInfo("C:\\");
        FileSystemInfo[] files = di.GetFileSystemInfos();
        var orderedFiles = files.OrderBy(f => f.CreationTime);
        

        编辑 - 抱歉,我没有注意到 .NET2.0 标记所以忽略 LINQ 排序。不过,使用 System.IO.DirectoryInfo.GetFileSystemInfos() 的建议仍然有效。

        【讨论】:

        • .Net2.0 中没有 LINQ,但仍然是迄今为止最好的答案。
        • 我不得不接受这个答案,因为当我今天回去实现它时,.Net 2.0 方法被称为 .GetFileSystemEntries,它仍然只返回一个字符串数组。
        • 乔尔,你看错了对象。 System.IO.Directory 具有 GetFileSystemEntries 方法。我的建议是改用 System.IO.DirectoryInfo,它具有 GetFileSystemInfos 方法。希望这会有所帮助。
        • 从技术上讲,您可以在 .NET 2 中执行 LINQ-to-Objects,这是您进行此类排序所需的全部内容。 albahari.com/nutshell/linqbridge.aspx
        • @ashes999 - LINQ 快乐还是密集/简洁代码快乐?我个人非常喜欢按照您建议的方式链接运算符,但它会使事情更难阅读/调试。
        【解决方案6】:

        只是一个想法。我喜欢找到一个简单的出路,并尝试重新使用已经可用的资源。如果我要对文件进行排序,我将只创建一个进程并将 syscal 设置为“DIR [x:\Folders\SubFolders*.*] /s /b /on”并捕获输出。

        使用系统的 DIR 命令可以排序:

        /O          List by files in sorted order.
        sortorder    N  By name (alphabetic)       S  By size (smallest first)
                     E  By extension (alphabetic)  D  By date/time (oldest first)
                     G  Group directories first    -  Prefix to reverse order
        
        The /S switch includes sub folders
        

        我不确定 D = By Date/Time 是否使用 LastModifiedDate 或 FileCreateDate。但是如果所需的排序顺序已经内置在 DIR 命令中,我将通过调用 syscall 来获得它。而且速度很快。我只是个懒惰的人;)

        经过一番谷歌搜索后,我找到了按特定日期/时间排序的开关:-

        /t [[:]TimeField] : Specifies which time field to display or use for sorting. The following list describes each of the values you can use for TimeField. 
        
        Value Description 
        c : Creation
        a : Last access
        w : Last written
        

        【讨论】:

          【解决方案7】:

          在 .NET 2.0 中,您需要使用 Array.Sort 对 FileSystemInfos 进行排序。

          此外,您可以使用 Comparer 委托来避免为比较而声明一个类:

          DirectoryInfo dir = new DirectoryInfo(path);
          FileSystemInfo[] files = dir.GetFileSystemInfos();
          
          // sort them by creation time
          Array.Sort<FileSystemInfo>(files, delegate(FileSystemInfo a, FileSystemInfo b)
                                              {
                                                  return a.LastWriteTime.CompareTo(b.LastWriteTime);
                                              });
          

          【讨论】:

          • 嘿克里斯,代码中的注释不正确吗?您声明按创建时间排序,但使用 LastWriteTime 不是 CreationTime?才意识到这条评论是如何面对的!
          【解决方案8】:

          您可以实现自定义 iComparer 来进行排序。阅读文件的文件信息并根据需要进行比较。

          IComparer comparer = new YourCustomComparer();
          Array.Sort(System.IO.Directory.GetFiles(), comparer);
          

          msdn info IComparer interface

          【讨论】:

            【解决方案9】:

            如果您想按创建日期等排序,您可能需要使用 DirectoryInfo.GetFiles,然后使用合适的谓词对结果数组进行排序。

            【讨论】:

              【解决方案10】:

              您可以编写一个自定义 IComparer 接口以按创建日期排序,然后将其传递给 Array.Sort。您可能还想查看 StrCmpLogical,它用于进行 Explorer 使用的排序(使用文本正确排序数字)。

              【讨论】:

                【解决方案11】:

                你是对的,默认是我的名字 asc。我发现更改排序顺序以从 FileInfo 集合创建数据表的唯一方法。

                然后您可以使用数据表中的 DefaultView 并使用 .Sort 方法对目录进行排序。

                这涉及到相当多而且相当缓慢,但我希望有人会发布更好的解决方案。

                【讨论】:

                • 默认是文件系统返回它们的顺序。如果您使用的是 NTFS,它们将是 alpha 排序的,但如果您使用的是 FAT32,它们将按表顺序返回(即,或多或少的创建顺序)。
                【解决方案12】:

                MSDN Documentation 声明不保证返回值的任何顺序。您必须使用 Sort() 方法。

                【讨论】:

                  【解决方案13】:

                  来自msdn

                  不保证返回文件名的顺序;如果需要特定的排序顺序,请使用 Sort() 方法。

                  Sort() 方法是标准的 Array.Sort(),它接受 IComparables(以及其他重载),因此如果您按创建日期排序,它将根据机器设置处理本地化。

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2020-03-21
                    • 1970-01-01
                    • 2016-03-01
                    • 2020-06-12
                    相关资源
                    最近更新 更多