HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2020
0608
kennoteloadを使用した際のファイルロックの方法を教えてください4解決


ken

リンク

2020/6/8(Mon) 10:07:37|NO.90718

notesaveやnoteloadを使用した際のファイルロックの方法について教えてください。
今、noteloadでtest.txt(テキストファイル)を読み込んで、スクリプトで処理したデータを追記した後に、noteseveで同じ(test.txt)ファイルに保存するスクリプトを作成しています。
スクリプトで行う処理にかかる時間はわずかだと思うのですが、他のユーザーがスクリプトで処理中に同じtest.txtにデータを書き込むと、処理が終わった後のデータで上書きされてしまいます。(実際に起こったことはないのですが、可能性はあると思うのです)
スクリプトで処理中にtest.txtをファイルロックする必要があると思うのですが、Windows APIがよく理解できていない私にはCreateFilenなどを使用する方法がどうにも理解できません。API関数を使用してロックをかけたり、解除する場合はnotesaveなどのHSPの命令は使用せず、すべてAPIを使用してファイルオープンから行わないといけないのではないかと理解しています。
今は、test.txtを処理中はリネームして他のユーザーからのアクセスを防いで、処理終了後test.txtに戻すという方法をとっています。でも、なんだかこの方法はそもそもおかしいのではないかと思っています。



この記事に返信する


沢渡

リンク

2020/6/8(Mon) 11:13:10|NO.90719

こんな感じで、テキストファイルを処理している間は「処理中」をあらわす目印ファイルを
作っておき、処理が終わったら削除するという方法はどうでしょうか?
実行開始時に目印ファイルがあるかどうかを調べ、あったら無くなるまで待つという形です。

//ロックファイルを作成 dummy=0 *lock_check exist "lock.tmp" if strsize!=-1 { dialog "他のユーザーがファイルを使用しています。\nしばらく待ってから[はい]を押してください。\n[いいえ]でこのソフトを終了します。",2 if stat=7 : end goto *lock_check } bsave "lock.tmp",dummy //メイン s="" notesel s exist "test.txt" if strsize!=-1 : noteload "test.txt" noteadd strf("%04u/%02u/%02u %02u:%02u:%02u",gettime(0),gettime(1),gettime(3),gettime(4),gettime(5),gettime(6)) mes s dialog "[OK]で保存します。" notesave "test.txt" //ロックファイルの削除 exist "lock.tmp" if strsize!=-1 : delete "lock.tmp" end



ken

リンク

2020/6/8(Mon) 11:41:38|NO.90720

沢渡様

ありがとうございます。
そうですね、対象とするファイルをリネームしてさらに元に戻すという操作に不安を感じていました。
ファイルのリネームは一旦、別ファイル名でコピーして、オリジナルのファイルを削除するという手順を踏んでいるとのことで、大切なデータファイルを対象にしているのでずーっと不安に感じていました。
色々考えていたのですがこんなシンプルな方法があることに気が付きませんでした。

これでしたらすぐに応用できます。



沢渡

リンク

2020/6/8(Mon) 19:31:37|NO.90722

すみません、少し手を加えました。
極めて可能性は低いと思いますが、ロックファイルの存在チェックから
ロックファイル作成までのごくわずかな時間の間はチェックをすり抜けてしまうので、
念のためにそれの対策もしました。
ランダムに生成した数値を「ID」としてロックファイルに書き込み、
本データ書き込みの前にIDが一致しているかどうかを確認しています。

randomize id0=rnd(32768)*rnd(32768) //IDを生成 //ロックファイルを作成 *lock_check exist "lock.tmp" if strsize!=-1 { dialog "他のユーザーがファイルを使用しています。\nしばらく待ってから[はい]を押してください。\n[いいえ]でこのソフトを終了します。",2 if stat=7 : end goto *lock_check } bsave "lock.tmp",id0,4 //メイン s="" notesel s exist "test.txt" if strsize!=-1 : noteload "test.txt" noteadd strf("%04u/%02u/%02u %02u:%02u:%02u",gettime(0),gettime(1),gettime(3),gettime(4),gettime(5),gettime(6)) mes s dialog "[OK]で保存します。" //保存前に再チェック flag=0 //何らかのトラブルが発生したフラグ exist "lock.tmp" if strsize=-1 { flag=1 } else { id1=0 bload "lock.tmp",id1,4 if id1!=id0 : flag=1 } if flag : dialog "セッションが中断されました。\n申し訳ございませんが、作業をやり直してください。" : goto *lock_check notesave "test.txt" //ロックファイルの削除 delete "lock.tmp" end



ken

リンク

2020/6/9(Tue) 08:43:39|NO.90723

沢渡様
提案していただいた方法でスクリプトを書き直してみました。実験しましたがロックファイル
の有無で確実に書き込みを阻止でき、以前リネームで行ったいた時よりも書き込み作業がが実感で
速くなりました。
ご指摘の通り、わずかな時間ですが割り込まれる可能性がありますね。早速改良します。
本当にご丁寧にありがとうございました。



ONION software Copyright 1997-2018(c) All rights reserved.