【VBScript極限攻略】数ギガバイトのログを秒殺する「メモリ節約型」ファイルパース術
業務自動化の世界で、我々が直面する最大の敵は「メモリ制限」と「非効率なI/O」です。特に、レガシーなWindows環境で数ギガバイトに及ぶ巨大なログファイルを扱う際、何も考えずに `ReadAll` や `ReadLine` をループさせるコードを書くのは「自殺行為」に等しい。
今日は、VBScriptにおけるFSO(FileSystemObject)の真の力を引き出し、メモリを一切圧迫せずに巨大ログのヘッダーを瞬時にスキップし、目的のデータのみを抽出する「極限の設計」を伝授する。
—
なぜ `ReadAll` ではいけないのか?
初級者が陥る最大の罠は、ファイルを全てメモリ上にロードしようとすることだ。VBScript(WScript.exe / CScript.exe)は32bitプロセスである以上、メモリ空間には限界がある。巨大ファイルを読み込めば、当然のごとく「メモリ不足(Out of Memory)」でスクリプトは沈黙する。
また、`ReadLine` で一行ずつ判定し、不要な行を捨て続ける手法も、文字列生成と破棄のオーバーヘッドによりパフォーマンスを著しく低下させる。
究極の解:`SkipLine` によるI/Oポインタの直接操作
我々が取るべき戦略は、「メモリ上にデータを保持しない」ことだ。FSOの `TextStream` オブジェクトが持つ `SkipLine` メソッドは、内部のファイルポインタを単に進めるだけで、文字列オブジェクトをメモリ上に生成しない。これこそが、高速かつ省メモリなパースの鍵となる。
—
実装:プロダクション級・高速ログスキップ・スクリプト
このコードは、堅牢性を重視しつつ、保守性を高めた設計となっている。そのまま業務ツールに組み込んで欲しい。
Option Explicit
‘ — 設定定数 —
Const FOR_READING = 1
Dim targetFilePath: targetFilePath = “C:\logs\large_server_log.txt”
Dim skipLinesCount: skipLinesCount = 1000000 ‘ スキップしたいヘッダー行数
Call ParseLargeLog(targetFilePath, skipLinesCount)
Sub ParseLargeLog(filePath, linesToSkip)
Dim fso, ts, currentLine
Set fso = CreateObject(“Scripting.FileSystemObject”)
‘ ファイルが存在しない場合や空の場合は即終了させる堅牢性
If Not fso.FileExists(filePath) Then
WScript.Echo “Error: File not found.”
Exit Sub
End If
Set ts = fso.OpenTextFile(filePath, FOR_READING)
‘ 1. メモリを消費しない高速スキップ
On Error Resume Next ‘ 途中でEOFに到達した場合の保護
Dim i
For i = 1 To linesToSkip
If ts.AtEndOfStream Then Exit For
ts.SkipLine
Next
On Error GoTo 0
‘ 2. 必要なデータ行のみを処理
‘ ここでは行ごとに処理するため、必要最低限のメモリしか消費しない
Do Until ts.AtEndOfStream
currentLine = ts.ReadLine
‘ 【重要】ここで行の解析を行う
‘ 巨大な処理をここで行う場合は、別関数に切り出し、
‘ オブジェクトのライフサイクルを明確にすること
If InStr(currentLine, “ERROR”) > 0 Then
WScript.Echo “Found Error: ” & currentLine
End If
Loop
‘ 3. リソースの確実な解放
ts.Close
Set ts = Nothing
Set fso = Nothing
End Sub
—
現場で「バグ」を生ませないための3つの鉄則
1. エラーハンドリングの徹底
`SkipLine` はファイル末尾に達した状態で実行するとランタイムエラーを発生させる。`AtEndOfStream` のチェックをループの直前に入れるのは必須の作法だ。
2. 文字コードの罠
`OpenTextFile` はデフォルトでASCII/ANSIとして読み込む。UTF-8のログを扱う場合は `ADODB.Stream` を使用すべきだ。FSOに固執して文字化けを引き起こすのはプロとして失格である。
3. データベース連携時の注意
ログをパースしてDB(SQL Server等)に流し込む際、一行ごとに `INSERT` を発行するのは低速すぎる。必ず「トランザクション」を張り、1,000行単位のバルクインサートを実装すること。I/O待機時間を最小化するのが、アーキテクトとしての腕の見せ所だ。
まとめ
VBScriptは古い言語かもしれないが、OSの深いレイヤーに直接アクセスできる強力なツールだ。`SkipLine` を使いこなし、不要なメモリ確保を極限まで排除すれば、数ギガバイトのログであっても、現代のモダンなスクリプト言語に引けを取らない速度で処理が可能になる。
コードは「書く」ものではなく「構築する」ものだ。この記事を読んだ君なら、もうメモリ不足で頭を抱えることはないはずだ。現場へ戻り、最高の結果を出してくれ。
