我有一个文件共享问题,我的进程正在尝试读取一个日志文件,而它目前仍由 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 文档,但它们只是支持我当前的心理模型,说明它应该如何工作,与它的工作方式相反。
以下是文档中的一些支持引用:
此枚举的典型用途是定义两个进程是否可以同时从同一个文件中读取。例如,如果打开一个文件并指定了读取,其他用户可以打开该文件进行读取但不能写入。
这是另一个宝石:
以下 FileStream 构造函数打开现有文件并授予其他用户只读访问权限 (Read)。
FileStream s2 = new FileStream(name, FileMode.Open, FileAccess.Read, FileShare.Read);
任何人都可以阐明这种行为。我正在.NET 4 % Windows XP 上对此进行测试。