У меня проблема с совместным доступом к файлам, когда мой процесс пытается прочитать файл журнала, пока он еще открыт 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))
{
}
Второй вызов конструктора 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))
{
}
Ум, да, запрашивая больше доступа при открытии второго потока, фактически обходит проблему. Я совершенно не понимаю, почему это так, и могу только предположить, что я что-то недопонимаю. Я прочитал документы API, но они просто поддерживают мою текущую ментальную модель, как это должно работать, вопреки тому, как она работает.
Ниже приведены некоторые поддерживающие цитаты из docs:
Типичное использование этого перечисления состоит в том, чтобы определить, являются ли два процесса может одновременно читать из того же файла. Например, если файл открыто и Чтение указано, другие пользователи могут открыть файл для но не для записи.
Вот еще один камень:
Следующий конструктор FileStream открывает существующий файл и предоставляет доступ только для чтения для других пользователей (Read).
FileStream s2 = new FileStream(name, FileMode.Open, FileAccess.Read, FileShare.Read);
Может ли кто-нибудь пролить свет на это поведение. Я тестирую это на .NET 4% Windows XP.