问题
是否File.AppendAllText
管理来自多个作者的冲突?
研究
我注意到MSDN 文档并没有真正提供任何一种方式,所以我决定反映代码并看看它做了什么。下面是调用的方法File.AppendAllText
:
private static void InternalAppendAllText(string path, string contents, Encoding encoding)
{
using (StreamWriter streamWriter = new StreamWriter(path, true, encoding))
{
streamWriter.Write(contents);
}
}
正如你所看到的,它只是利用了一个StreamWriter
. 所以,如果我们更深入地研究它,特别是它使用的构造函数,我们会发现它最终调用了这个构造函数:
internal StreamWriter(string path, bool append, Encoding encoding, int bufferSize, bool checkHost) : base(null)
{
if (path == null)
{
throw new ArgumentNullException("path");
}
if (encoding == null)
{
throw new ArgumentNullException("encoding");
}
if (path.Length == 0)
{
throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath"));
}
if (bufferSize <= 0)
{
throw new ArgumentOutOfRangeException("bufferSize", Environment.GetResourceString("ArgumentOutOfRange_NeedPosNum"));
}
Stream streamArg = StreamWriter.CreateFile(path, append, checkHost);
this.Init(streamArg, encoding, bufferSize, false);
}
具有以下值:
path: the path to the file
append: the text to append
encoding: UTF8NoBOM
bufferSize: 1024
checkHost: true
并且进一步我们发现,base(null)
实现除了设置InternalFormatProvider
为null
. 所以,如果我们继续挖掘,我们会发现CreateFile
:
private static Stream CreateFile(string path, bool append, bool checkHost)
{
FileMode mode = append ? FileMode.Append : FileMode.Create;
return new FileStream(path, mode, FileAccess.Write, FileShare.Read, 4096, FileOptions.SequentialScan, Path.GetFileName(path), false, false, checkHost);
}
FileStream
使用这些参数值创建一个:
path: the path to the file
mode: FileMode.Append
access: FileAccess.Write
share: FileShare.Read
bufferSize: 4096
options: FileOptions.SequentialScan
msgPath: just the file name of the path provided
bFromProxy: false
useLongPath: false
checkHost: true
所以现在我们终于到达了某个地方,因为我们即将利用 Windows API,这就是问题真正开始的地方,因为它FileStream::ctor
调用了一个名为Init
. 这是一个相当长的方法,但我真的对一行很感兴趣:
this._handle = Win32Native.SafeCreateFile(text3,
dwDesiredAccess,
share,
secAttrs,
mode,
num,
IntPtr.Zero);
当然调用CreateFile
,其中参数值是:
text3: the full path to the file
dwDesiredAccess: 1073741824
share: 1 (FILE_SHARE_READ)
secAttrs: null
mode: 4 (OPEN_ALWAYS)
num: 134217728 | 1048576 (FILE_FLAG_SEQUENTIAL_SCAN | FILE_FLAG_POSIX_SEMANTICS)
那么,如果我有两个线程试图同时访问同一路径的该调用,Windows 会怎么做?它会打开文件并缓冲写入,以便允许两个消费者写入文件吗?还是我需要利用锁定对象并lock
围绕对 的调用AppendAllText
?