文件共享无法按预期工作

Ken*_*art 14 .net c# file-sharing file-security

我有一个文件共享问题,我的进程正在尝试读取日志文件,而它当前仍由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))
{
}
Run Code Online (Sandbox Code Playgroud)

第二个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)
Run Code Online (Sandbox Code Playgroud)

尽管事实上第一个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))
{
}
Run Code Online (Sandbox Code Playgroud)

嗯,是的,在打开第二个流时请求更多访问实际上绕过了问题.我完全不知道为什么会这样,只能假设我误解了一些事情.我已经阅读了API文档但他们只是支持我当前的心智模型,了解它应该如何工作,与它的工作原理相反.

以下是文档中的一些支持引用:

此枚举的典型用法是定义两个进程是否可以同时从同一文件读取.例如,如果打开文件并指定了Read,则其他用户可以打开文件进行读取但不能写入.

这是另一个宝石:

以下FileStream构造函数打开现有文件并授予对其他用户的只读访问权限(读取).

FileStream s2 = new FileStream(name, FileMode.Open, FileAccess.Read, FileShare.Read);

任何人都可以对这种行为有所了解.我正在.NET 4%Windows XP上测试它.

Han*_*ant 15

 var fileStream2 = new FileStream(..., FileShare.Read)
Run Code Online (Sandbox Code Playgroud)

这让很多程序员兴奋不已.每个人都认为这增加了阅读共享.它没有,原始文件访问请求已经允许读取并再次指定它不会改变任何东西.相反,它否认写共享.这是行不通的,因为有人已经获得了写入权限.并且正在使用它,你无法删除该权利.因此,您访问该文件的请求将失败.

必须包含FileShare.Write.