VBScriptを極める:FSOによる高速・堅牢なフォルダ同期アーキテクチャの真髄
VBScriptは「レガシー」と呼ばれ久しい。しかし、Windowsの根幹を成すWSH(Windows Script Host)の実行環境は、現代の肥大化したフレームワークが届かない領域で、今なお極めて軽量かつ強力な自動化の武器として君臨している。
特にファイルシステムオブジェクト(FSO)を用いた同期処理は、そのメモリ効率とAPIの親和性において、中途半端な高レイヤー言語よりもはるかに「現場的」な解となり得る。今回は、単なるコピーではなく、生存戦略としての「差分同期アルゴリズム」を提示する。
—
1. 勘違いされた「同期処理」とメモリ管理の現実
多くのエンジニアが陥る罠は、`FileSystemObject`のインスタンスをループ内で安易に生成・破棄し、その結果として発生するメモリリークやハンドル枯渇に無自覚であることだ。VBScriptのガベージコレクションは頼りにならない。
真のアーキテクトが守るべき鉄則:
- Objectのスコープ制御: インスタンスはルートで生成し、再利用せよ。
- Late Bindingの活用とリスク: インスタンス化のコストを抑えるため、型指定を避け、必要に応じて例外処理(On Error Resume Next)でガードする。
- I/Oのボトルネック回避: ファイル比較はメタデータ(`DateLastModified`)のみに絞り、中身のハッシュ比較は最終手段とする。
—
2. 堅牢な差分同期スクリプト:実装の核心
以下は、読み取り元(Source)と保存先(Target)のタイムスタンプを比較し、新しいものだけを転送するロジックだ。
‘ — 極限のファイル同期スクリプト —
Option Explicit
Dim fso, oSource, oTarget, oFile
Set fso = CreateObject(“Scripting.FileSystemObject”)
‘ 同期設定
Dim srcDir, dstDir
srcDir = “C:\SourcePath”
dstDir = “D:\TargetPath”
SyncFolders srcDir, dstDir
‘ 終了処理:参照の明示的な破棄
Set fso = Nothing
Sub SyncFolders(sourcePath, targetPath)
Dim oFolder, oSubFolder, oTargetFile
If Not fso.FolderExists(targetPath) Then fso.CreateFolder(targetPath)
Set oFolder = fso.GetFolder(sourcePath)
‘ ファイル比較・コピー
For Each oFile In oFolder.Files
Dim targetFilePath
targetFilePath = fso.BuildPath(targetPath, oFile.Name)
If Not fso.FileExists(targetFilePath) Then
‘ 新規ファイルは即時コピー
oFile.Copy targetFilePath, True
Else
‘ 更新日時の比較による差分判定
Set oTargetFile = fso.GetFile(targetFilePath)
If oFile.DateLastModified > oTargetFile.DateLastModified Then
oFile.Copy targetFilePath, True
End If
End If
Next
‘ 再帰的処理:サブフォルダの同期
For Each oSubFolder In oFolder.SubFolders
SyncFolders oSubFolder.Path, fso.BuildPath(targetPath, oSubFolder.Name)
Next
End Sub
—
3. シニアエンジニアが意識すべき「APIの深淵」
パフォーマンスの最適化:パス解決のオーバーヘッド
`fso.BuildPath`は便利だが、頻繁に呼び出すと文字列結合のコストが積み重なる。数万ファイル規模の同期を行う場合、パス文字列の構築は最小限に抑えるべきだ。また、共有ネットワーク越し(UNCパス)の場合、APIのタイムアウト挙動に注意が必要である。
大規模データへの対応:エラーハンドリングの哲学
`On Error Resume Next`を無闇に乱用してはならない。同期中にアクセス拒否(Access Denied)が発生した際、スクリプトが停止するのか、ログを残してスキップするのか。「停止させない」ことが目的ではなく、「整合性を保ったままどこまで継続できるか」がプロの仕事である。
Windows API呼び出しの検討
もし、`DateLastModified`の精度(FAT32/NTFSの差異)で問題が発生する場合、`WMI (Windows Management Instrumentation)` を経由して `CIM_DataFile` クラスを叩く必要がある。VBScriptの標準FSOでは取得できないファイル属性が必要な時、`GetObject(“winmgmts:…”)`への移行が、次の一手となる。
—
結論:VBScriptを使い倒すということ
現代のスクリプト環境(PowerShellなど)は、確かに高機能だ。しかし、環境構築が制限されたレガシーなWindows Serverにおいて、VBScriptは唯一無二の存在である。
今回提示したコードは、あくまで「骨子」だ。ここにログ出力機能、転送失敗時のリトライロジック、あるいは排他制御の概念を積み上げることで、貴方の環境における「最強の同期エンジン」へと昇華させてほしい。
ツールに振り回されるな。ツールの特性を理解し、その限界ギリギリまでを使い尽くすことこそが、エンジニアとしての真の技術力である。
