現在 NLog によってまだ開かれている間に、プロセスがログ ファイルを読み込もうとしているというファイル共有の問題があります。この問題を診断したところ、驚くべきことがわかりました。以下は失敗します。
using (var fileStream1 = new FileStream("test.file", FileMode.Append, FileAccess.Write, FileShare.Read))
using (var fileStream2 = new FileStream("test.file", FileMode.Open, FileAccess.Read, FileShare.Read))
{
}
2 番目のFileStream
コンストラクター呼び出しは次のエラーで失敗します。
System.IO.IOException was unhandled
Message=The process cannot access the file 'c:\...\test.file' because it is being used by another process.
Source=mscorlib
StackTrace:
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath)
at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share)
FileStream
これは、最初のものは読書を共有する意欲を示しているという事実にもかかわらずです. さらに驚いたのは、これが機能することです。
using (var fileStream1 = new FileStream("test.file", FileMode.Append, FileAccess.Write, FileShare.Read))
using (var fileStream2 = new FileStream("test.file", FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
}
ええと、はい、2 番目のストリームを開くときに追加のアクセスを要求すると、実際には問題が回避されます。なぜそうなのか、私は完全に困惑しており、何かを誤解しているとしか思えません。API ドキュメントを読みましたが、実際の動作とは逆に、これがどのように動作するかについて、現在のメンタル モデルをサポートしているだけです。
ドキュメントからの補足的な引用を次に示します。
この列挙型の一般的な用途は、2 つのプロセスが同じファイルから同時に読み取ることができるかどうかを定義することです。たとえば、ファイルが開かれ、読み取りが指定されている場合、他のユーザーはそのファイルを読み取り用に開くことはできますが、書き込み用には開くことができません。
ここに別の宝石があります:
次の FileStream コンストラクターは、既存のファイルを開き、他のユーザーに読み取り専用アクセス (読み取り) を許可します。
FileStream s2 = new FileStream(name, FileMode.Open, FileAccess.Read, FileShare.Read);
誰でもこの動作に光を当てることができますか? これを .NET 4 % Windows XP でテストしています。