742просмотров
31 марта 2025 г.
question📷 ФотоScore: 816
Зачем нужен Open Statement, когда есть FSO? Думаю, как многие из вас, я мало задумывался над тем каким способом читать текстовые файлы. FileSystemObject (FSO) — удобно, просто, работает. И вот наступил момент, когда любопытство взяло верх: решил проверить на практике, насколько велика разница. 🖥 Тест: три способа чтения, один большой файл Для теста я взял обычный текстовый файл объемом около 200 Мб (для наглядности) и выбрал три разных подхода для чтения данных:
▶️FSO — привычный способ через OpenTextFile().ReadAll()
▶️Open For Input — построчное чтение
▶️Open For Binary Access Read — побайтовое чтение всего файла за раз Результаты оказались весьма показательными (скрин ниже).
Binary Access просто разорвал конкурентов на больших объемах.
Там, где FSO и Input начинают тупить, Binary метод справляется моментально. ℹ️ Сразу оговорюсь:
на маленьких файлах разница практически незаметна, но когда дело доходит до больших объемов, Binary Access просто творит чудеса! 👏 🧑💻 Код для теста Можно потестить у себя.
Просто вставьте код ниже в любой модуль, сохраните файл в удобном месте, разместите рядом текстовый файл test.txt для теста или укажите свое имя в константе FILE_PATH.
'@Folder("VBAProject")
Option Explicit Const FILE_PATH As String = "test.txt" Public Sub Run() Const LINE_SEP As String = "------------" FileSystem.ChDir ThisWorkbook.Path FSORead Debug.Print LINE_SEP RegularRead Debug.Print LINE_SEP BinaryRead Debug.Print LINE_SEP
End Sub Public Sub RegularRead() Dim t As Single t = DateTime.Timer Dim n As Integer n = FileSystem.FreeFile() Dim Buffer() As String ReDim Buffer(255) Dim i As Long Open FILE_PATH For Input As #n While Not FileSystem.EOF(n) If i > UBound(Buffer) Then ReDim Preserve Buffer(Conversion.CLng(UBound(Buffer) 1.5)) End If Line Input #n, Buffer(i) i = i + 1 Wend Close #n ReDim Preserve Buffer(i - 1) Dim Data As String Data = Strings.Join(Buffer, vbNewLine) Debug.Print "RegularRead:", "Reading time: "; (DateTime.Timer - t) 1000 & "ms" Debug.Print "RegularRead:", "Data len: "; Strings.Len(Data)
End Sub Public Sub BinaryRead() Dim t As Single t = DateTime.Timer Dim n As Integer n = FileSystem.FreeFile() Dim i As Long Open FILE_PATH For Binary Access Read As #n Dim Buffer() As Byte ReDim Buffer(FileSystem.LOF(n) - 1) Get #n, , Buffer Close #n Dim Data As String Data = Strings.StrConv(Buffer, vbUnicode) Debug.Print "BinaryRead:", "Reading time: "; (DateTime.Timer - t) 1000 & "ms" Debug.Print "BinaryRead:", "Data len: "; Strings.Len(Data)
End Sub Public Sub FSORead() Dim t As Single t = DateTime.Timer Dim FSO As FileSystemObject Set FSO = New FileSystemObject Dim Data As String Data = FSO.OpenTextFile(FILE_PATH, ForReading).ReadAll() Debug.Print "FSORead:", "Reading time: "; (DateTime.Timer - t) 1000 & "ms" Debug.Print "FSORead:", "Data len: "; Strings.Len(Data)
End Sub Stay tuned❤️ Дневник VBAшника