【テクニカル・上級編】【改行コード整形】CRLF / LF / CR が混在するテキストファイルをFSOで標準化(CRLF変換)するスクリプト – VBScript (Visual Basic Scripting Edition)解析バイブル

スポンサーリンク

異種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環境においてこれほど低負荷で、インストール不要で動作するツールは他にない。このスクリプトをタスクスケジューラに組み込み、ファイル監視と連携させることで、レガシーなデータ連携基盤は、驚くほど堅牢なアーキテクチャへと進化する。

道具が古いのではない。使い手が「枯れた技術」をどう再解釈するかが、エンジニアの真価を問うのである。

次の現場でも、このロジックを迷わず活用してほしい。健闘を祈る。

タイトルとURLをコピーしました