Можно ли читать файлы в порядке изменения даты? - PullRequest
0 голосов
/ 22 апреля 2019

Моему макросу нужно будет прочитать очень большой каталог файлов и проанализировать данные из них. Этот каталог периодически обновляется, поэтому я пытаюсь оптимизировать свою программу так, чтобы она читала только те файлы, которые были добавлены с момента последнего запуска программы.

Пока что с помощью FileSystemObject кажется, что я могу читать файлы только по алфавиту, если я не ошибаюсь.

Лучшее решение, которое у меня есть, - это каждый раз читать все файлы, создавать массив, содержащий информацию о файлах, сортировать по DateModified, а затем открывать только те файлы, которые мне нужны. Мне интересно посмотреть, смогу ли я пропустить этот шаг, читая файлы в порядке DateModified.

Заранее спасибо.

1 Ответ

0 голосов
/ 28 апреля 2019

Shell кажется хорошим вариантом здесь - хотя я не сравнивал производительность с FSO.Например, вы могли бы рассмотреть команду forfiles, которая позволяет получать файлы, измененные после указанной даты?

Пример кода для этого может быть следующим:

Public Sub RunMe()
    Dim fileNames As Collection
    Dim path As String
    Dim dat As Date
    Dim file As Variant

    'Set the path and 'find after' date.
    path = "c:\user\documents"
    dat = #1/1/2018#

    'Fetch the files, setting mask as required.
    'This example is fetching all .txt files.
    Set fileNames = GetFilesModifiedAfter(path, dat, "*.txt")

    'Process the list of files.
    If Not fileNames Is Nothing Then
        For Each file In fileNames
            ' ... do stuff here.
            Debug.Print path & "\" & file
        Next
    End If

End Sub

Private Function GetFilesModifiedAfter( _
    path As String, _
    after As Date, _
    Optional mask As String) As Collection

    Dim cmd As String
    Dim piped() As String
    Dim result As Collection
    Dim i As Long

    'Build the command string.
    'Date must be formatted as MM/DD/YYYY.
    cmd = "cmd.exe /s /c forfiles /p " & _
        """" & path & """" & _
        " /d +" & Format(after, "mm/dd/yyyy")

    'Add the mask if passed-in.
    If mask <> vbNullString Then cmd = cmd & " /m " & mask

    'Execute the command and split by /r/n.
    piped = Split(CreateObject("WScript.Shell").Exec(cmd).StdOut.ReadAll, vbCrLf)

    'Leave if nothing is returned.
    If UBound(piped) = -1 Then Exit Function

    'Poplate the result collection,
    'and remove the leading and trailing inverted commas.
    Set result = New Collection
    For i = 0 To UBound(piped)
        If Len(piped(i)) > 2 Then
            result.Add Mid(piped(i), 2, Len(piped(i)) - 2)
        End If
    Next

    'Return the result collection.
    Set GetFilesModifiedAfter = result
End Function

Обновление

Я только что провел некоторое тестирование, и кажется, что FSO быстрее, конечно, в папках, содержащих менее 100 файлов.Было бы интересно запустить это на действительно больших папках (скажем, на тысяче файлов), поскольку я инстинктивно чувствую, что Shell может иметь преимущество в производительности.Однако на данный момент вот версия FSO:

Private Function GetFilesModifiedAfter2( _
    path As String, _
    after As Date, _
    mask As String) As Collection

    Dim fso As Object, file As Object
    Dim result As Collection

    'Instance of objects.
    Set fso = CreateObject("Scripting.FileSystemObject")
    Set result = New Collection

    'Iterate the files and test date last modified property.
    For Each file In fso.GetFolder(path & "\").Files
        If file.Name Like mask And file.DateLastModified > after Then
            result.Add file.Name
        End If
    Next

    'Return the result collection.
    Set GetFilesModifiedAfter2 = result
End Function
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...