数ギガバイトのログも怖くない!VBScriptで「メモリを食わずに」高速パースする極意
こんにちは。システム自動化の現場でVBScriptと長年向き合ってきたエンジニアです。
皆さんは、数ギガバイトにも及ぶ巨大なログファイルを前に、フリーズする画面を見つめて絶望したことはありませんか?「とりあえず全部読み込んでから処理しよう」とすると、VBScriptはメモリを浪費し、OSの仮想メモリを圧迫してPCは悲鳴を上げます。
今回は、「必要な行だけを、メモリを節約しながら最速で叩く」という、プロの現場で必須のテクニックを伝授します。これさえマスターすれば、VBScriptは「古い言語」から「強力な自動化兵器」へと姿を変えます。
—
1. なぜ「全部読み込み」は悪手なのか?
VBScriptでファイルを開く際、`ReadAll`メソッドで全データを一度に変数に格納するのは、小さな設定ファイルなら問題ありません。しかし、ギガ単位のログでそれをやると、VBScriptはデータをすべてメモリ上に展開しようとします。
メモリ不足(Out of Memory)のエラーが出るか、OSがディスクへのスワップを繰り返して処理が終わらなくなるのがオチです。
私たちが目指すのは、「ストリーム(流れる水)のように読み込み、不要な部分は読み飛ばす」という手法です。
—
2. 魔法のメソッド:`SkipLine` を使いこなす
`FileSystemObject (FSO)` には、ファイルを読み込むためのメソッドがいくつかありますが、今回は以下の2つを組み合わせます。
- `SkipLine`: 1行を読み飛ばしてカーソルを次の行へ進める(メモリに展開しない)。
- `ReadLine`: 必要な行だけをメモリに読み込む。
図解するならこんなイメージです。
[ログファイル]
(1) ヘッダー行1 —-> SkipLine (ポイッ!)
(2) ヘッダー行2 —-> SkipLine (ポイッ!)
(3) 必要なログデータ –> ReadLine (ここだけ取得!)
これなら、ファイルが10GBあっても、メモリ消費量は「1行分」で済みます。
—
3. 実装コード:高速スキップ・パースのテンプレート
現場ですぐに使える、堅牢なテンプレートです。
Option Explicit
‘ メイン処理
Call ProcessLargeLog(“C:\Logs\huge_data.log”, 100) ‘ 最初の100行をスキップする例
Sub ProcessLargeLog(filePath, skipCount)
Dim fso, file, i, lineData
Set fso = CreateObject(“Scripting.FileSystemObject”)
‘ ファイルが存在するか確認
If Not fso.FileExists(filePath) Then
WScript.Echo “ファイルが見つかりません: ” & filePath
Exit Sub
End If
‘ ファイルを読み取り専用で開く (ForReading = 1)
Set file = fso.OpenTextFile(filePath, 1)
‘ 指定した行数分だけスキップ処理
On Error Resume Next ‘ 万が一ファイルの終端を超えたときのエラー回避
For i = 1 To skipCount
If Not file.AtEndOfStream Then
file.SkipLine
Else
Exit For
End If
Next
On Error GoTo 0
‘ 残りの行を必要な分だけ読み込む
Do Until file.AtEndOfStream
lineData = file.ReadLine
‘ — ここにパース処理を書く —
‘ 例: 特定のキーワードが含まれる行だけ表示
If InStr(lineData, “ERROR”) > 0 Then
WScript.Echo “発見: ” & lineData
End If
‘ —————————-
Loop
‘ 後処理:オブジェクトの解放(メモリ管理の基本)
file.Close
Set file = Nothing
Set fso = Nothing
WScript.Echo “処理が完了しました。”
End Sub
—
4. 陥りやすいエラーと対策
初心者がこのコードを書く際、よくハマるポイントが2つあります。
① 「ファイルの終端」でエラーになる
`SkipLine`をループさせている時、ファイルの全行数より多い回数を指定すると「入力インデックスが範囲外です」というエラーが出ます。
- 対策: コード内に入れた `If Not file.AtEndOfStream Then` のチェックが命綱です。これを忘れると、ログの途中で処理が止まってしまいます。
② ファイルを閉じ忘れる
VBScriptは終了時に自動解放されますが、巨大なファイルを扱うスクリプトがループ処理などで複数動く場合、`file.Close` を忘れるとファイルロックが残ります。
- 対策: `Set file = Nothing` と合わせて、必ず明示的にクローズしましょう。
—
5. まとめ:プロへの一歩
今回の技術の本質は、「リソース(メモリ)を必要な分だけ確保し、不要なものを保持しない」というエンジニアリングの原則にあります。
- `ReadAll` は小さなデータに。
- `SkipLine` + `ReadLine` は巨大なデータに。
この使い分けができるようになれば、あなたはもう「マクロを記録する人」ではありません。「業務を自動化し、リソースを最適化するアーキテクト」です。
次は、この技術を使って、特定の条件でログを分割するスクリプトに挑戦してみるのも面白いですよ。VBScriptの世界は、まだまだ奥が深いです。応援しています!
