如何按文件名和编号对文件列表进行排序?

sca*_*t17 2 linq vb.net sorting

我在一个目录中有一堆文件,我试图根据它们的类型来获取它们。一旦我拥有它们,我想按文件名对它们进行排序(其中有一个数字,我想以这种方式对它们进行排序)

我返回的文件是:

file-1.txt
file-2.txt
...
file-10.txt
file-11.txt
...
file-20.txt
Run Code Online (Sandbox Code Playgroud)

但我得到它们的顺序看起来更接近于这个:

file-1.txt
file-10.txt
file-11.txt
...
file-2.txt
file-20.txt
Run Code Online (Sandbox Code Playgroud)

现在我正在使用Directory.GetFiles()并尝试使用该linq OrderBy房产。但是,我在排序文件列表(如上面的第一个列表)时需要执行的操作非常失败。

Directory.GetFiles()似乎正在返回字符串列表,因此我无法获取文件属性列表,例如filenamename

这是我目前的代码:

documentPages = Directory.GetFiles(documentPath, "*.txt").OrderBy(Function(p) p).ToList()
Run Code Online (Sandbox Code Playgroud)

有人有什么想法吗?

Ňɏs*_*arp 5

听起来您可能正在寻找“自然排序” - 文件资源管理器用于对包含数字的文件名进行排序的显示类型。为此,您需要一个自定义比较器:

Imports System.Runtime.InteropServices

Partial Class NativeMethods
    <DllImport("shlwapi.dll", CharSet:=CharSet.Unicode)>
    Private Shared Function StrCmpLogicalW(s1 As String, s2 As String) As Int32
    End Function

    Friend Shared Function NaturalStringCompare(str1 As String, str2 As String) As Int32
        Return StrCmpLogicalW(str1, str2)
    End Function
End Class

Public Class NaturalStringComparer
    Implements IComparer(Of String)

    Public Function Compare(x As String, y As String) As Integer Implements IComparer(Of String).Compare
        Return NativeMethods.NaturalStringCompare(x, y)
    End Function
End Class
Run Code Online (Sandbox Code Playgroud)

用它来对你得到的结果进行排序:

Dim myComparer As New NaturalStringComparer

' OP post only shows the filename without path, so strip off path:
' (wont affect the result, just the display)
Dim files = Directory.EnumerateFiles(path_name_here).
                 Select(Function(s) Path.GetFileName(s)).ToList
Console.WriteLine("Before: {0}", String.Join(", ", files))

' sort the list using the Natural Comparer:
files.Sort(myComparer)
Console.WriteLine("After: {0}", String.Join(", ", files))
Run Code Online (Sandbox Code Playgroud)

结果(单行以节省空间):

之前:file-1.txt、file-10.txt、file-11.txt、file-19.txt、file-2.txt、file-20.txt、file-3.txt、file-9.txt、 file-99.txt
之后:file-1.txt、file-2.txt、file-3.txt、file-9.txt、file-10.txt、file-11.txt、file-19.txt、file -20.txt,文件-99.txt

这样做的优点之一是它不依赖于特定的模式或编码。它更加通用,可以处理文本中的多个数字:

权力的游戏\4 - 群鸦的盛宴\1 - Prologue.mp3 权力
的游戏\4 - 群鸦的盛宴\2 - 先知.mp3
...
权力的游戏\4 - 群鸦的盛宴\10 - 布蕾妮II.mp3
权力的游戏\4 - 群鸦的盛宴\11 - 珊莎.mp3


ANatural String Sort非常方便,我个人不介意通过创建扩展来污染 Intellisense:

' List<string> version
<Extension>
Function ToNaturalSort(l As List(Of String)) As List(Of String)
    l.Sort(New NaturalStringComparer())
    Return l
End Function

' array version
<Extension>
Function ToNaturalSort(a As String()) As String()
    Array.Sort(a, New NaturalStringComparer())
    Return a
End Function
Run Code Online (Sandbox Code Playgroud)

现在使用更加容易:

Dim files = Directory.EnumerateFiles(your_path).
              Select(Function(s) Path.GetFileName(s)).
              ToList.
              ToNaturalSort()

' or without the path stripping:
Dim files = Directory.EnumerateFiles(your_path).ToList.ToNaturalSort()
Run Code Online (Sandbox Code Playgroud)