異種OS混在環境における「改行コードの深淵」:FSOを極限まで使い倒す標準化戦略
WindowsとLinuxが混在する現代のエンタープライズ環境において、最も軽視され、かつ最もシステムを崩壊させるトリガーとなるのが「改行コードの不整合」だ。
特に、レガシーなバッチ処理やファイル連携基盤において、`LF`のみのテキストファイルが紛れ込んだ瞬間に、後続のCSVインポートや解析エンジンが沈黙する。これを「テキストエディタで開き直して保存」などという手作業で解決しようとするのは、エンジニアとしての敗北である。
今日は、VBScriptにおけるFSO(File System Object)の限界と、それを突破するためのメモリ管理、そして確実な変換ロジックを提示する。
—
1. なぜFSOの `ReadAll` をそのまま使ってはいけないのか
多くの初学者は、`OpenTextFile` から `ReadAll` を行い、`Replace` 関数で改行を置換しようとする。小規模なログファイルならそれで十分だ。しかし、数メガバイトを超えるデータや、システム連携の基幹プロセスでこれを行うと、VBScriptのメモリ管理の甘さが露呈し、メモリリークやプロセス肥大化を招く。
我々が目指すべきは、「巨大なファイルをストリームとして扱い、バッファリングを意識した非破壊的変換」である。
2. 鋼鉄の標準化ロジック:CRLF変換エンジン
以下のコードは、単なる置換処理ではない。バイナリ的な視点を持ち込み、OS固有の改行コードをWindows標準の `CRLF` (0x0D 0x0A) へと強制的に正規化する設計だ。
‘ ==============================================================================
‘ Title: Stream-based Line-Ending Normalizer (LF/CR -> CRLF)
‘ Author: Chief Architect
‘ Description: FSOを用いたメモリ効率を考慮した改行コード標準化ツール
‘ ==============================================================================
Option Explicit
Const ForReading = 1, ForWriting = 2
Dim fso, objInput, objOutput
Dim strContent, strPath, strOutputPath
strPath = “C:\Data\Input\legacy_data.txt”
strOutputPath = “C:\Data\Output\normalized_data.txt”
Set fso = CreateObject(“Scripting.FileSystemObject”)
‘ ファイル存在確認の原則
If Not fso.FileExists(strPath) Then
WScript.Echo “Error: Target file not found.”
WScript.Quit
End If
‘ ストリームの確保と正規化処理
‘ 読み込みはTristateFalse(ASCII)で行い、バイト単位の制御を維持する
Set objInput = fso.OpenTextFile(strPath, ForReading, False)
Set objOutput = fso.CreateTextFile(strOutputPath, True)
Do Until objInput.AtEndOfStream
‘ 1行ずつ読み込み、CRLFを一時的に退避し、LF/CRをCRLFに置換して書き出す
‘ 正規表現(RegExp)を使用せず、Replaceの連鎖で処理する方がVBSでは低コスト
strContent = objInput.ReadLine
‘ LF(vbLf) と CR(vbCr) を CRLF(vbCrLf) に集約
‘ 既にCRLFになっている箇所を重複させないための賢い置換ロジック
strContent = Replace(strContent, vbCrLf, vbLf)
strContent = Replace(strContent, vbCr, vbLf)
strContent = Replace(strContent, vbLf, vbCrLf)
objOutput.WriteLine strContent
Loop
‘ オブジェクトの明示的解放(メモリ管理の鉄則)
objInput.Close
objOutput.Close
Set objInput = Nothing
Set objOutput = Nothing
Set fso = Nothing
WScript.Echo “Normalization Complete: ” & strOutputPath
—
3. チーフアーキテクトの視点:技術的要点
① `ReadLine` を選ぶ理由
巨大なファイルを扱う際、`ReadAll` はメモリを食いつぶす。`ReadLine` を用いることで、OSのバッファサイズに応じた適度なメモリ占有率を維持できる。これが「安定稼働」を支える差だ。
② 置換ロジックの「二段構え」
`Replace(strContent, vbCrLf, vbLf)` を最初に行うのは、既にCRLFである箇所を「一旦LFに変換」して保護するためだ。その後、すべての改行をCRLFに統一する。この手順を誤ると、CRLFが `CRCRLF` に化けるという、よくあるバグに直面することになる。
③ オブジェクトの明示的解放
VBScriptのガベージコレクションを信じてはいけない。`Set obj = Nothing` を行うことは、システムリソースをOSへ即座に返却するための「礼儀」であり、長期間稼働するタスクスケジューラ上での必須事項である。
4. 最後に:レガシーを「負債」にするな
VBScriptは古いが、Windows環境においてこれほど低負荷で、インストール不要で動作するツールは他にない。このスクリプトをタスクスケジューラに組み込み、ファイル監視と連携させることで、レガシーなデータ連携基盤は、驚くほど堅牢なアーキテクチャへと進化する。
道具が古いのではない。使い手が「枯れた技術」をどう再解釈するかが、エンジニアの真価を問うのである。
次の現場でも、このロジックを迷わず活用してほしい。健闘を祈る。
