gpt4 book ai didi

c# - File.AppendAllText 是否管理冲突(即多用户并发)?

转载 作者:可可西里 更新时间:2023-11-01 07:57:27 30 4
gpt4 key购买 nike

问题

File.AppendAllText 是否管理来自多个作者的冲突?

研究

我注意到 MSDN documentation并没有真正提供任何一种方式,所以我决定我会反射(reflect)代码并看看它做了什么。下面是从 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 调用了一个名为 初始化。这是一个很长的方法,但我对其中一行非常感兴趣:

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 会怎么做?它会打开文件并缓冲写入,以便两个消费者都可以写入文件吗?或者我是否需要在调用 AppendAllText 时利用锁定对象和 lock

最佳答案

只有一个会赢得写入,这将是第一个,任何后续尝试都将失败,直到释放写锁(即刷新缓冲区并关闭文件) - 但是,它可以同时打开以供读取(权限取决于)。

Read - Allows subsequent opening of the file for reading. If this flag is not specified, any request to open the file for reading (by this process or another process) will fail until the file is closed. However, even if this flag is specified, additional permissions might still be needed to access the file.

关于c# - File.AppendAllText 是否管理冲突(即多用户并发)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16083520/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com