问题描述
我遇到一个文件共享问题,我的进程正在尝试读取日志文件,而NLog当前仍在打开该文件.在诊断问题时,我发现了一些令人惊讶的事情.以下失败:
I have a file sharing issue where my process is trying to read a log file whilst it is currently still open by NLog. In diagnosing the issue, I found something surprising. The following fails:
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
构造函数调用失败,并显示以下信息:
The second FileStream
constructor call fails with:
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
表示它愿意共享阅读,但事实并非如此.我发现更令人惊讶的是,这种方法有效:
This is despite the fact that the first FileStream
indicates its willingness to share reading. What I found even more surprising was that this works:
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))
{
}
嗯,是的,打开第二个流时请求 more 访问实际上绕过了问题.我完全不知道为什么会这样,只能假设我误会了一些东西.我已经阅读了API文档,但是他们只是支持我当前的思维模型,说明它应该如何工作,而不是它如何工作.
Um, yes, requesting more access when opening the second stream actually bypasses the issue. I am completely baffled as to why that is the case, and can only assume I am misunderstanding something. I've read through the API docs but they just support my current mental model for how this should work, contrary to how it does work.
以下是文档中的一些支持报价:
Here are some supporting quotes from the docs:
这是另一个宝石:
FileStream s2 = new FileStream(name, FileMode.Open, FileAccess.Read, FileShare.Read);
任何人都可以阐明这种行为.我正在.NET 4%Windows XP上对此进行测试.
Can anyone shed any light on this behavior. I'm testing this on .NET 4 % Windows XP.
推荐答案
var fileStream2 = new FileStream(..., FileShare.Read)
这使很多程序员感到震惊.每个人都认为此添加阅读共享.事实并非如此,原始文件访问请求已允许读取并再次指定它不会更改任何内容.相反,它拒绝写入共享.那是行不通的,因为有人已经拥有写访问权限.并且正在使用它,您不能删除该权利.因此,您访问文件的请求将失败.
This trips up lots of programmers. Everybody assumes that this added read sharing. It didn't, the original file access request already allowed reading and specifying it again doesn't change anything. Instead it denies write sharing. And that cannot work because somebody already got write access. And is using it, you cannot remove that right. So your request to access the file will fail.
您必须包括FileShare.Write.
You must include FileShare.Write.
这篇关于文件共享未按预期工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!