2010-11-29 24 views
5

FileStreamコンストラクタを使用して、一度に1つのプロセスだけがファイルにアクセスできるようにすることはできますか?次のコードは動作しますか?FileStreamを使用してファイルロックを実装できますか?

public static IDisposable AcquireFileLock() { 
    IDisposable lockObj; 
    do { 
     // spinlock - continually try to open the file until we succeed 
     lockObj = TryOpenLockFile(); 

     // sleep for a little bit to let someone else have a go if we fail 
     if (lockObj == null) Thread.Sleep(100); 
    } 
    while (lockObj == null); 

    return lockObj; 
} 

private static FileStream TryOpenLockFile() { 
    try { 
     return new FileStream(s_LockFileName, FileMode.Create, FileAccess.Read, FileShare.None); 
    } 
    catch (IOException) { 
     return null; 
    } 
} 

具体的には、FileMode.CreateアトミックWRTの他のプロセスの動作ですか?私が使っているはずのものがありますか?

EDIT:具体的には、これはMicrosoft CLR上で、1台のマシン上のローカルファイルを使用して行われます。

+0

これは良い見えます!しかし、誰がロックファイルをクリーンアップしますか? 'FileStream'呼び出しは常に既存のロックファイルを上書きするので、おそらくこれを行う必要はありません。 –

+0

クリーンアップのために、私はいつも '{File.Delete(...)}'を試して例外を無視することができました...( – thecoop

答えて

2

これは、あなたが望むことをします。 FileShare.Noneは重要な部分です。

すべてのライターアプリが同じコンピュータにある場合は、物理的なファイルを必要とせずに同じ目標を達成するために、または最後にファイルに書き込みを気にしない場合にファイルアクセスを仲介することもできます(書き込みは同時ではありません)。これにより、毎回ファイルを開く必要がなくなり、Sleepループ(より良いperf)の代わりにブロッキングセマンティックを提供できるようになります。

名前が秘密として扱われていない場合、つまりプロセスを安全に保つ必要がある情報は、ファイル(Mutex)でスクワットすることがあります。これは動作します

+2

)Mutexは同じコンピューター。ファイルロックはネットワーク上で動作します。 – Gabe

+0

@Gabe - ユースケースが何であるかはっきりしていませんが、あなたは正しいです –

1

、次の点に注意与えられた:

  • (モノを経由して、Linux上で、ファイルロックが助言しているので、これはホールドアップしませんので、あなたの方法は常に成功し)あなたは、Windows上にある

    • をあなたは、ローカルファイルへのアクセス(SMBもおそらく動作しますが、しかし、NFSまたはWebDAVはほぼ確実ではないだろう)
    • はIOExceptionが、おそらく広すぎるキャッチされている、あなたは具体的には、共有違反のため失敗したことを確認する必要があり
  • +0

    IOExceptionは、ファイルが既にロックされているときにスローされるものです。より具体的なものは見つかりません:/ – thecoop

    +0

    HResultを確認することができますWin32エラーコードを持っているか、それに失敗している場合は、メッセージテキストをチェックすることができます –

    関連する問題