2011-12-22 2 views
0

폴더의 특정 유형의 파일을 나열하고 ListView에서 렌더링하는 간단한 (ASP.NET) 웹 페이지가 있습니다.FileInfoComparer가 올바르게 정렬되지 않았습니다. (LastWriteTime에서)

나는 역순으로 내림차순으로 LastWriteTime을 정렬하여 정렬하려고했습니다. 그러나 정렬 프로세스가 배열의 순서를 변경하더라도 올바르게 정렬하지는 않습니다. 예를 들어, LastWriteTime이 #6/3/2011 12:00:00 인 항목은 목록의 맨 위에 있지만, LastWriteTime이 #12/16/2011 12:00:00 인 다른 항목은 정렬 후 목록의 중간에 있습니다.

왜 그런가?

코드 :

 Dim dirInfo As New DirectoryInfo(Server.MapPath(AppSettings.Item("ContentDir"))) 
     Dim FileArrayList As New ArrayList(dirInfo.GetFiles("*.msg", SearchOption.TopDirectoryOnly)) 

     Dim SortDirections As New Dictionary(Of String, SqlClient.SortOrder) 

     With FileArrayList 
      .TrimToSize() 
      .Sort(New FileInfoComparer(SqlClient.SortOrder.Descending, "LastWriteTime")) 
     End With 

FileInforComparer 클래스 :

LastWriteTime이 정렬 순서를 설명하는 문자열로 반환 될 수 있습니다
Imports System.IO 
Imports System.Reflection 


Public Class FileInfoComparer 
    Implements IComparer 

    Private _sortOrder As System.Data.SqlClient.SortOrder 
    Private _sortColumn As String 

    ''' <summary> 
    ''' Constructs new Comparer object, using the supplied SortOrder and SortColumn parameters 
    ''' </summary> 
    ''' <param name="sortOrder">Defines the SortOrder for the comparison</param> 
    ''' <param name="sortColumn">Defines which column is sorted</param> 
    ''' <remarks></remarks> 
    Public Sub New(ByVal sortOrder As System.Data.SqlClient.SortOrder, ByVal sortColumn As String) 
     _sortOrder = sortOrder 
     _sortColumn = sortColumn 
    End Sub 


    ''' <summary> 
    ''' Defines the Sorting mechanism for FileInfo objects 
    ''' </summary> 
    ''' <param name="x">First FileInfo object to compare</param> 
    ''' <param name="y">Second FileInfo object to compare</param> 
    ''' <returns></returns> 
    ''' <remarks></remarks> 
    Public Overridable Overloads Function Compare(ByVal x As Object, ByVal y As Object) As Integer Implements System.Collections.IComparer.Compare 

     Dim oX_PI As PropertyInfo = CType(x, FileInfo).GetType.GetProperty(_sortColumn) 
     Dim oY_PI As PropertyInfo = CType(y, FileInfo).GetType.GetProperty(_sortColumn) 
     Dim Result As Int16 = oX_PI.GetValue(x, Nothing).CompareTo(oY_PI.GetValue(x, Nothing)) 

     'If DESC then reverse the result 
     If _sortOrder = SqlClient.SortOrder.Descending Then Result = Result * -1 

     Return Result 

    End Function 
End Class 
+1

처럼, 다음 종료 .ToList()를 추가하여 수행 할 수있는 List<FileInfo>를 사용하는 것이 좋습니다'FileInfoComparer'는 표준 아닙니다 클래스, 나는 믿는다 ... –

+0

예, 맞습니다 - 서둘러 게시! 코드 스 니펫을 업데이트했습니다. – CJM

+0

어떤 버전의 .NET을 사용하고 있습니까? LINQ에 접근 할 수 있다면'Sort' 메소드를 사용하지 않는 것이 좋을까요? – cadrell0

답변

3

. 값은 DateTime 객체가 아니라 문자열로 정렬됩니다. 문자열을 datetime으로 구문 분석하고 정렬 순서가 정확해야합니다.

+0

날짜별로 정렬하지 않을 수도 있지만 텍스트별로 정렬되지는 않습니다. 나는 이것을 고려했다. 그러나 정직하기 위해, 나는 분류 기준을 이해할 수 없다. 그럼에도 불구하고 날짜를 구체적으로 처리하도록 코드를 수정 해 보겠습니다. – CJM

+0

'oX_PI.GetValue (x, Nothing)'에게 말할 수있는 한 Date 객체를 반환합니다. .ComppareTo가 Date 객체를 올바르게 비교하지 못합니까? – CJM

+0

날짜가 올바르게 비교되었습니다. –

1

다음은 LINQ를 사용하는 솔루션입니다. 이것은 VB에서 C# 및 converted으로 작성되었으므로 잘 작동합니다.

Dim dirInfo = New DirectoryInfo(Server.MapPath(AppSettings.Item("ContentDir"))) 
Dim fileList = dirInfo.GetFiles("*.msg", SearchOption.TopDirectoryOnly).OrderByDescending(Function(f) f.LastWriteTime) 

fileList의 유형은 IEnumerable<FileInfo> 될 것입니다. 당신이 오히려 ArrayList을 사용하는 것보다, AA 변경 가능한 목록이 될 필요가 있다면, 내가 그렇게

Dim fileList = dirInfo.GetFiles("*.msg", SearchOption.TopDirectoryOnly).OrderByDescending(Function(f) f.LastWriteTime).ToList()