这并非不可能,您实际上不需要使用 Apppend = true 初始化的 StreamWriter。您需要做的就是使用 FileStream.Seek() 来确保“文件指针”位于文件末尾。此示例 C# 代码运行良好:
using (var fs = new FileStream(@"c:\temp\test.txt", FileMode.Open,
FileAccess.ReadWrite, FileShare.Read)) {
var sr = new StreamReader(fs); // NOTE: not using using
string txt = sr.ReadToEnd();
fs.Seek(0, SeekOrigin.End); // Be sure
var sw = new StreamWriter(fs);
sw.WriteLine("appended");
sw.Flush();
}
请注意此代码中相当多的不适。我将从您的首选值 FileShare.Read 开始。这意味着您将在修改文件时让另一个进程读取该文件。这个过程很有可能会在没有通知的情况下对这个文件中出现的字节感到有点困惑。可以很好地工作,FileShare.None 确保您的代码永远不会导致任何类型的事故。强力推荐。
下一个标志是 // 注意不使用 using。这很重要,因为 StreamReader 将对您传递的流承担“责任”。如果您在 .NET 代码中执行标准的正确操作,则该类将在 Using 语句结束其范围时关闭流。这不是你想要的,你想保留文件以便你可以写入它。
Seek() 调用执行 StreamWriter 构造函数的 Append 参数所做的事情,确保您附加到文件,而不是从头开始随机覆盖文件的某些部分。由于您要追加,因此确保文件中的旧数据被截断没有问题。
Flush 调用是这里的臭味。您必须调用它来强制编写器刷新其输出缓冲区。如果你不这样做,你写的内容的随机位将从文件中丢失。这通常不是问题,因为您会调用 Close() 或使用 Using 语句来确保编写器已关闭。不是在这种情况下,FileStream 正在发号施令,它会在此处正确关闭文件,但它不知道另一个作家加入了潮流并想要写入。
这将起作用,但它打破了相当多的教条。更典型的模式是 open-read + read + close,open-createnew + write + close。并处理 open-createnew 可能因另一个进程抓取文件而失败的可能性。多任务操作系统的危害,始终准备好应对。