2017年3月2日木曜日

ネゴシエーション式ファイルロック

複数のPCから一つのファイルに対してRead・Writeが同時に行われる可能性がある場合、誰かが更新作業中はファイルをロックして更新できない状態にしておかないとファイルの中身の整合性が失われてしまうケースがあります。

そのようなケースを回避するためのサンプルを作成しました。


※このサンプルで実施できる「ロック」は、「仲間内でのお約束」的なロックです。この方法によってロックしていることを知らない人がダイレクトにファイルにアクセスした場合に対しては、このサンプルが用いる「ロック」は無力です。

以下ソース
<html>
<title>lock</title>
<body style="text-align:center;overflow:hidden">
<input id=inp style="width:100%;text-align:center">
<button id=btnLS>lock開始</button>
<button id=btnLE>lock解除</button>
<textarea id=ta style="width:100%;height:100px;" wrap=off></textarea>
<button id=btnR>Read</button>
<button id=btnW>Write</button>
</body>
<script>
resizeTo(250,250)
fso=function(){
var fs=new ActiveXObject('Scripting.FileSystemObject')
return {
AXO:fs,
gsf2:fs.GetSpecialFolder(2), // Z:\TEMP
Read:function(path, swCreate, swUnicode){
if(!fs.FileExists(path)){return}
with(fs.OpenTextFile(path, 1, swCreate, swUnicode)){ var str=AtEndOfStream ? '' : ReadAll(); Close() }
return str
},
Write:function(path,str,swUnicode,sw上書きしない){ with(fs.CreateTextFile(path, !sw上書きしない, swUnicode)){ Write(str); Close() } },
Lock:function(path){
var pathL=path+'.lock', ws, wsn=new ActiveXObject('WScript.Network')
try{
ws=fs.CreateTextFile(pathL)
ws.Write(wsn.computerName+'\r\n'+wsn.userName)
return {Close:function(){ ws.Close(); fs.DeleteFile(pathL) }}
}
catch(e){
return this.Read(pathL)
}
}
}
}()
inp.value = fso.gsf2+'\\lockTest.txt'
objLock = null
btnLS.onclick=function(){
var obj=fso.Lock(inp.value)
if(!obj.Close){return alert('Lock失敗\n\n'+obj)}
this.innerText = 'lock中'
this.disabled = true
objLock = obj
}
btnLE.onclick=function(){
if(!objLock){return alert('lockしていません')}
objLock.Close()
objLock = null
btnLS.disabled = false
}
btnR.onclick=function(){ ta.value = fso.Read(inp.value) }
btnW.onclick=function(){ fso.Write(inp.value, ta.value) }
</script>
</html>



実行画面





「lock開始」ボタンを押すとインプットボックス内に記載されたPathのファイルを「ロックしています!と宣言」します。(path+".lock"というファイルができているのがその宣言の証)



この「*.lock」ファイルはlock中はhtaから書き込みストリームが開きっぱなしの状態になっているので、削除したり、他のhtaから書き込みストリームを開くことができません。



ロックしたいファイルのPath+".lock"というPathに対して書き込みストリームを開ければロック成功、開けなければロック失敗という独自のルールを作って、整合性を保ちたいファイルを保護しています。
その独自のルールに従うプログラムの間でのみ、このロックは意図通りに機能します。

0 件のコメント:

コメントを投稿