在 C# 中同时读写文件

Posted

技术标签:

【中文标题】在 C# 中同时读写文件【英文标题】:simultaneous read-write a file in C# 【发布时间】:2011-04-18 13:32:21 【问题描述】:

我有一个文件,其中包含我想要监控更改以及添加我自己的更改的数据。像“Tail -f foo.txt”一样思考。

基于this thread,看起来我应该只创建一个文件流,然后将它同时传递给写入器和读取器。但是,当阅读器到达原始文件的末尾时,它看不到我自己编写的更新。

我知道这似乎是一个奇怪的情况......它更像是一个实验,看看它是否可以完成。

这是我尝试过的示例:


foo.txt: 一个 b c d 电子 f


        string test = "foo.txt";
        System.IO.FileStream fs = new System.IO.FileStream(test, System.IO.FileMode.OpenOrCreate, System.IO.FileAccess.ReadWrite);

        var sw = new System.IO.StreamWriter(fs);
        var sr = new System.IO.StreamReader(fs);

        var res = sr.ReadLine();
        res = sr.ReadLine();
        sw.WriteLine("g");
        sw.Flush();
        res = sr.ReadLine();
        res = sr.ReadLine();
        sw.WriteLine("h");
        sw.Flush();
        sw.WriteLine("i");
        sw.Flush();
        sw.WriteLine("j");
        sw.Flush();
        sw.WriteLine("k");
        sw.Flush();
        res = sr.ReadLine();
        res = sr.ReadLine();
        res = sr.ReadLine();
        res = sr.ReadLine();
        res = sr.ReadLine();
        res = sr.ReadLine();

读过“f”后,reader返回null。

【问题讨论】:

张贴者确实提出了一些关于让两个文件流指向同一个对象的内容......确实有效。即使读取器到达文件末尾,如果写入器更新,读取器流也会获得两个结果。 是的,那是我删除了我的帖子,因为它没有像我预期的那样工作。我取消删除它并解释了原因... 【参考方案1】:

好的,稍后进行两次编辑...

这应该可行。第一次尝试时,我想我忘记在 oStream 上设置 FileMode.Append。

string test = "foo.txt";

var oStream = new FileStream(test, FileMode.Append, FileAccess.Write, FileShare.Read); 
var iStream = new FileStream(test, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); 

var sw = new System.IO.StreamWriter(oStream);
var sr = new System.IO.StreamReader(iStream); 
var res = sr.ReadLine(); 
res = sr.ReadLine();
sw.WriteLine("g"); 
sw.Flush(); 
res = sr.ReadLine();
res = sr.ReadLine();
sw.WriteLine("h"); sw.Flush();
sw.WriteLine("i"); sw.Flush(); 
sw.WriteLine("j"); sw.Flush(); 
sw.WriteLine("k"); sw.Flush(); 
res = sr.ReadLine(); 
res = sr.ReadLine(); 
res = sr.ReadLine();
res = sr.ReadLine();
res = sr.ReadLine();
res = sr.ReadLine();

【讨论】:

我更改了 oStream 的 FileShare.ReadWrite 。【参考方案2】:

@mikerobi 是正确的,当您写入流时,文件指针会更改并移动到流的末尾。您不指望的是 StreamReader 有自己的缓冲区。它从文件中读取 1024 个字节,您将从该缓冲区中获得结果。直到缓冲区用完,所以它必须再次从 FileStream 中读取。什么也找不到,因为文件指针在文件末尾。

您确实需要分离 FileStreams,每个文件流都有自己的文件指针,才有希望完成这项工作。

【讨论】:

感谢 Hans,我希望在自己开发解决方案时确认这一事实。看到我似乎得出了相同的结论,这很有帮助。【参考方案3】:

我相信每次你写一个字符时,你都在推进流位置,所以下一次读取尝试在你刚刚写的字符之后读取。发生这种情况是因为您的流阅读器和流编写器使用相同的 FileStream。使用不同的文件流,或在每次写入后在流中寻找 -1 个字符。

【讨论】:

好吧,我交错写入和读取的方式是看看是否是这种情况。阅读器仍然按顺序正确阅读,只是看不到作者添加的任何新数据。【参考方案4】:

您不太可能对涉及使用相同流进行读取和写入的任何解决方案感到满意。如果您尝试使用 StreamReader 读取文件的尾部,则尤其如此。

您希望拥有两个不同的文件流。如果您愿意,写入流可以是StreamWriter。读取流应该是二进制流(即使用File.OpenReadFileStream.Create 创建),从文件中读取原始字节,然后转换为文本。我对this question 的回答展示了它是如何完成的基础知识。

【讨论】:

以上是关于在 C# 中同时读写文件的主要内容,如果未能解决你的问题,请参考以下文章

c#中文件读写StreamWriter问题

C#读写二进制文件

C# 读写Ini文件

C#使用读写锁三行代码简单解决多线程并发写入文件时线程同步的问题

C# winform Win7 C盘读写文件 没有权限

☀️ 学会编程入门必备 C# 最基础知识介绍—— C# 高级文件操作(文本文件的读写二进制文件的读写Windows 文件系统的操作)