VBScriptを用いて、テキストファイル(CSV形式)の最終行のデータのみを高速で取り出す方法を試行錯誤してみる
(1) 1行ずつ順番に読み込んで、最後の行まで到達する方法
Option Explicit
On Error Resume Next
Dim objFSO ' FileSystemObject
Dim objFile ' ファイル読み込み用
Dim strTemp
Const ForReading = 1, ForWriting = 2, ForAppending = 3
Dim tmStart, tmEnd ' 実行時間計測用
tmStart = Timer ' 開始時間
Set objFSO = CreateObject("Scripting.FileSystemObject")
If Err.Number = 0 Then
Set objFile = objFSO.OpenTextFile("f:\temp\test.csv", ForReading)
If Err.Number = 0 Then
' 1行ずつEOFまで読み込む
Do While objFile.AtEndOfStream <> True
strTemp = objFile.ReadLine
Loop
objFile.Close
Else
strTemp = "読み込みエラー"
End If
Else
strTemp = "ファイルが開けない"
End If
tmEnd = Timer ' 終了時間
tmEnd = tmEnd - tmStart ' 実行時間を得る
MsgBox(strTemp + " : " + FormatNumber(tmEnd,10) + " sec")
(2)全行を一気に読み込み、Split関数で配列に切り分ける方法
Option Explicit
On Error Resume Next
Dim objFSO ' FileSystemObject
Dim objFile ' ファイル読み込み用
Dim strAll ' ファイル全体を一旦読み込むバッファ
Dim arrAll
Dim strTemp
Const ForReading = 1, ForWriting = 2, ForAppending = 3
Dim tmStart, tmEnd ' 実行時間計測用
tmStart = Timer ' 開始時間
Set objFSO = CreateObject("Scripting.FileSystemObject")
If Err.Number = 0 Then
Set objFile = objFSO.OpenTextFile("f:\temp\test.csv", ForReading)
If Err.Number = 0 Then
strAll = objFile.ReadAll ' ファイル全てをバッファに格納
objFile.Close
arrAll = Split(strAll, vbCrLf) ' 配列に切り分けて格納
strTemp = arrAll(Ubound(arrAll)-1) ' 最終要素のみ取り出す
Else
strTemp = "読み込みエラー"
End If
Else
strTemp = "ファイルが開けない"
End If
tmEnd = Timer ' 終了時間
tmEnd = tmEnd - tmStart ' 実行時間を得る
MsgBox(strTemp + " : " + FormatNumber(tmEnd,10) + " sec")
655350行のデータで試してみたところ
(1)の場合、1.625秒
(2)の場合、2.172秒
ログデータを頻繁に読み込まないといけない場合、これではCPUに負荷を掛けてしまうので不適切なプログラムになってしまう。
で、考えたのが、決め打ちで「シーク」する方法。1行のデータが、明らかに32バイトに収まると仮定して…
Option Explicit
On Error Resume Next
Dim objFSO ' FileSystemObject
Dim objFile ' ファイル読み込み用
Dim strAll ' ファイル全体を一旦読み込むバッファ
Dim strLastPart
Dim arrAll
Dim strTemp
Const ForReading = 1, ForWriting = 2, ForAppending = 3
Dim tmStart, tmEnd ' 実行時間計測用
tmStart = Timer ' 開始時間
Set objFSO = CreateObject("Scripting.FileSystemObject")
If Err.Number = 0 Then
Set objFile = objFSO.OpenTextFile("f:\temp\test.csv", ForReading)
If Err.Number = 0 Then
strAll = objFile.ReadAll ' ファイル全てをバッファに格納
objFile.Close
strLastPart = Right(strAll, 32) ' バッファの後ろから32バイトを切り出す
arrAll = Split(strLastPart, vbCrLf)
strTemp = arrAll(Ubound(arrAll)-1)
Else
strTemp = "読み込みエラー"
End If
Else
strTemp = "ファイルが開けない"
End If
tmEnd = Timer ' 終了時間
tmEnd = tmEnd - tmStart ' 実行時間を得る
MsgBox(strTemp + " : " + FormatNumber(tmEnd,10) + " sec")
このようにすると、実行時間が 0.28秒。