【テクニカル・上級編】【上級プロフェッショナル向け】フォルダ双方向同期における「タイムスタンプ衝突(両方変更)」を検知して安全退避する自動解決ロジック – VBScript (Visual Basic Scripting Edition)解析バイブル

スポンサーリンク

VBScriptを極める:ファイル同期における「タイムスタンプ衝突」の完全制御と安全退避ロジック

VBScriptという言語は、現代のクラウドネイティブな開発環境から見れば「化石」のように見えるかもしれない。しかし、製造業の現場や堅牢性が求められるレガシーなオンプレミス環境において、これほど低レイテンシでWindows OSの深層に直結できるツールは他にない。

今日論じるのは、ただのファイルコピーではない。「双方向同期におけるタイムスタンプ衝突」という、分散システムにおける最も厄介な事象を、いかにFSO(FileSystemObject)で安全に処理するかという極限の知見だ。

1. 衝突検知の設計思想:なぜ「上書き」が許されないのか

同期エンジンにおいて、A地点とB地点の両方でファイルが更新された場合、単純なタイムスタンプ比較では「後勝ち」になる。しかし、どちらの変更も捨てられないビジネス要件がある場合、それはデータ損失(ロスト)を意味する。

真のプロフェッショナルが実装すべきは、以下の3ステップだ。

1. メタデータ比較: `DateLastModified` を比較するが、絶対値で判断しない。
2. 衝突判定: 両方のタイムスタンプが「基準時刻(前回の同期時刻)」より新しい場合、それは「衝突」とみなす。
3. アトミックな退避: 競合したファイルを削除せず、タイムスタンプを付与した別名で保存する。

2. 衝突解決ロジックの実装(VBScript)

以下のコードは、単なるスクリプトではない。メモリ管理とオブジェクトのライフサイクルを考慮した、現場仕様のエンジンだ。

‘ — 極限のファイル同期ロジック: 衝突検知エンジン —
Option Explicit

Dim fso, folderA, folderB
Set fso = CreateObject(“Scripting.FileSystemObject”)

‘ メモリ最適化: オブジェクトを必要最小限のスコープで扱う
‘ 大量ファイル処理時は、各ファイル処理後に明示的なNothing代入を行うこと
Sub SynchronizeFiles(pathA, pathB, lastSyncTime)
Dim fileA, fileB, targetPath

Set folderA = fso.GetFolder(pathA)

For Each fileA In folderA.Files
If fso.FileExists(pathB & “\” & fileA.Name) Then
Set fileB = fso.GetFile(pathB & “\” & fileA.Name)

‘ 衝突検知: 両ファイルが最終同期時刻より後に更新されているか
If fileA.DateLastModified > lastSyncTime And fileB.DateLastModified > lastSyncTime Then
Call HandleCollision(fileA, fileB)
ElseIf fileA.DateLastModified > fileB.DateLastModified Then
fileA.Copy fileB.Path, True
End If

Set fileB = Nothing
End If
Next

‘ メモリ解放の徹底
Set folderA = Nothing
End Sub

Sub HandleCollision(fA, fB)
Dim timestamp
‘ タイムスタンプをリネーム用の文字列に変換 (YYYYMMDDHHMMSS)
timestamp = Year(Now) & Right(“0” & Month(Now), 2) & Right(“0” & Day(Now), 2) & _
Right(“0” & Hour(Now), 2) & Right(“0” & Minute(Now), 2)

‘ 安全退避: 衝突したファイルAを別名で保存
fA.Copy fB.ParentFolder.Path & “\” & fA.Name & “.CONFLICT_” & timestamp, False

‘ ログ記録: 監査証跡を残すことはエンジニアの責務
WScript.Echo “CONFLICT DETECTED: ” & fA.Name & ” at ” & Now
End Sub

3. なぜこの設計が必要なのか(アーキテクトの視点)

オブジェクトのメモリ管理

VBScriptのエンジンである `wscript.exe` は、長時間のループ処理においてメモリリークが発生しやすい。特に `FileSystemObject` は、ループ内でインスタンスを乱造するとスタックを圧迫する。常に `Set obj = Nothing` でデストラクタを明示的に呼び出す癖をつけろ。

ファイルシステムの「揺らぎ」を吸収する

ファイルシステムは、ネットワークドライブ経由の場合、タイムスタンプの精度に「誤差(Clock Skew)」が生じることがある。厳密な同期を行うなら、FSOの `DateLastModified` だけでなく、Win32 APIの `GetFileTime` を呼び出し、ナノ秒単位での比較を行う実装も視野に入れるべきだ。

ログの重要性

衝突時にファイルを退避させる際、必ず「なぜ衝突したか」というメタデータ(または同期元情報)をログに書き出せ。管理者が後から「あのファイルはどこへ消えた?」と問う事態を未然に防ぐのが、アーキテクトの仕事である。

4. 結び:レガシーを「保守」ではなく「昇華」させる

VBScriptを使い続けることは、決して古いことではない。OSの深層に触れ、メモリの挙動を制御し、競合という不確実性に論理で立ち向かう。このプロセスこそが、エンジニアとしての基礎体力を養う。

もし君が現在、大規模な同期システムの崩壊に悩んでいるのなら、まずはこの「衝突検知リネーム」を導入することから始めよ。エラーを隠蔽せず、「衝突を可視化する」ことこそが、システムを堅牢にする唯一の近道だ。

コードは嘘をつかない。君が書いたロジックが、システムを静かに、そして確実に守り抜くことを期待している。

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