【VBScript極意】ギガバイト級のログも一瞬で。ADODB.Streamで実現する「超高速行数カウント」の技術
こんにちは。自動化の現場で数々の苦難を乗り越えてきたエンジニアです。
皆さんは、数GBある巨大なログファイルの行数を数えるとき、どうしていますか?
「`FileSystemObject` (FSO) の `ReadLine` を使ってループさせている」という方。そのコード、今すぐ書き換えましょう。
FSOは便利ですが、数百万行を超えるファイルでそのアプローチを取ると、OSのI/Oを無駄に占有し、処理が終わる頃にはコーヒーが冷めきってしまいます。
今回は、VBScriptのポテンシャルを極限まで引き出し、メモリを効率的に使いながら爆速で行数をカウントする「ADODB.Streamバッファ読み込み術」を伝授します。
—
なぜ、ReadLineではいけないのか?
FSOの `ReadLine` は、内部で「改行コードを見つけるまで文字列を構築してメモリに展開する」という処理を繰り返します。ファイルが巨大になればなるほど、この「メモリ確保と解放」のオーバーヘッドが積み重なり、処理速度が急激に低下するのです。
一方、今回紹介する `ADODB.Stream` は、ファイルを「ストリーム(データの川)」として扱い、巨大なバッファ(塊)を一気にメモリへ引き込みます。 あとはその塊の中で、改行文字(`vbLf`)がいくつ含まれているかを数えるだけ。
考え方はシンプルですが、これだけで処理速度は数十倍から数百倍に跳ね上がります。
—
爆速カウントを実現する実装コード
以下のコードをコピーして `.vbs` ファイルとして保存し、コマンドプロンプトやダブルクリックで実行してみてください。
‘ ADODB.Stream を活用した超高速行数カウント
Option Explicit
Const adTypeBinary = 1
Dim filePath, lineCount
‘ 調査対象のパスを指定
filePath = “C:\logs\huge_log_file.log”
WScript.Echo “集計開始…”
lineCount = CountLinesFast(filePath)
WScript.Echo “総行数: ” & lineCount
Function CountLinesFast(path)
Dim stream, buffer, i, count
Dim fso : Set fso = CreateObject(“Scripting.FileSystemObject”)
‘ ファイルが存在しない場合は終了
If Not fso.FileExists(path) Then Exit Function
Set stream = CreateObject(“ADODB.Stream”)
stream.Type = adTypeBinary ‘ バイナリモードで開く(最速)
stream.Open
stream.LoadFromFile path
‘ 64KB単位で読み込み(OSのバッファサイズと相性が良い)
Const CHUNK_SIZE = 65536
count = 0
Do While Not stream.EOS
buffer = stream.Read(CHUNK_SIZE)
‘ バイナリデータ内の改行コード(LF: 10)をカウントする
Dim b
For i = 1 To LenB(buffer)
If AscB(MidB(buffer, i, 1)) = 10 Then
count = count + 1
End If
Next
Loop
stream.Close
CountLinesFast = count
End Function
—
コードのポイント:ここが「プロ」の領域
このコードがなぜ速いのか、その秘密を解説します。
1. `adTypeBinary`(バイナリモード)の採用
テキストモードで開くと、VBScriptは文字コード変換(Shift-JISやUTF-8の判定など)を裏で行います。これが重いのです。バイナリとして読み込むことで、変換コストをゼロにしています。
2. `Read(CHUNK_SIZE)` によるバッファリング
1行ずつではなく、64KBという大きな塊でメモリに読み込みます。ディスクヘッドの移動回数を最小限に抑える、I/O最適化の基本テクニックです。
3. `AscB` と `MidB` の活用
文字列操作関数(`Asc`, `Mid`)ではなく、バイナリ専用の `AscB`, `MidB` を使うことで、文字コード変換を介さない超高速なバイト比較を行っています。
—
初学者が陥りやすいエラーと回避策
- 「そんな大きなファイル、メモリに乗るの?」という誤解
今回のアプローチは `CHUNK_SIZE` で細かく刻んでいるため、ファイルが10GBあっても、一度にメモリを消費するのは指定した64KB分だけです。メモリ不足(OutOfMemory)を気にする必要はありません。
- 改行コードの罠
Windowsの改行コードは `CR+LF` (13 + 10) です。今回のコードはシンプルにするために `LF` (10) だけをカウントしていますが、実務では「CR+LFを1行としてカウントする」ために、少しロジックを調整する必要がある場合もあります(今回はLFのみで十分なケースが多いです)。
- 権限エラー
ログファイルが別のプロセスで開かれている場合、`LoadFromFile` でエラーが出ることがあります。その際は、`FileSystemObject` で一度別の場所へコピーしてから処理するか、共有モードを意識した設計が必要です。
—
最後に:自動化の先にあるもの
「マクロの記録」で生成されたコードを動かすだけなら、誰にでもできます。しかし、「なぜそのコードが遅いのか?」「OSはどうやってデータを処理しているのか?」という視点を持てば、VBScriptのような枯れた言語であっても、最新のスクリプト言語に劣らない性能を引き出すことができます。
この `ADODB.Stream` の使い方は、ファイル操作の基本にして究極です。ぜひ、あなたの現場の「重たい処理」に適用してみてください。
ここをクリアすれば、あなたはもうただの初心者ではありません。システムの本質を見極めるエンジニアへの第一歩を踏み出したのです。応援していますよ!
