C# 中同时读写文件

发布于 2024-09-25 11:15:18 字数 1202 浏览 8 评论 0原文

我有一个包含数据的文件,我想监视这些数据的更改,并添加我自己的更改。像“Tail -f foo.txt”一样思考。

基于这个线程,看起来我应该创建文件流,并将其传递给写入器和读取器。然而,当读者到达原始文件的末尾时,它看不到我自己编写的更新。

我知道这看起来很奇怪……这更像是一个实验,看看是否可以做到。

这是我尝试过的示例:


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”后,读取器返回 null。

I have a file containing data that I'd like to monitor changes to, as well as add changes of my own. Think like "Tail -f foo.txt".

Based on this thread, it looks like I should just create a filestream, and pass it both to a writer and reader. However, when the reader reaches the end of the original file, it fails to see updates I write myself.

I know it seems like a weird situation... its more an experiment to see if it can be done.

Here is the example case I tried:


foo.txt:
a
b
c
d
e
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();

After getting past "f", the reader returns null.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

北斗星光 2024-10-02 11:15:18

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

这应该可行。我第一次尝试时,我想我忘记了在 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();

Ok, two edits later...

This should work. The first time I tried it I think I had forgotten to set FileMode.Append on the oStream.

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();
地狱即天堂 2024-10-02 11:15:18

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

您确实需要分离 FileStream,每个 FileStream 都有自己的文件指针才能实现此目的。

@mikerobi is correct, when you write to the stream the file pointer is changed and moved to the end of the stream. What you are not counting on is that StreamReader has its own buffer. It reads 1024 bytes from the file and you'll get results from that buffer. Until the buffer runs out so it has to read from the FileStream again. Finding nothing because the file pointer is at the end of the file.

You really do need to separate FileStreams, each with their own file pointer to have any hope of making this work.

花之痕靓丽 2024-10-02 11:15:18

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

I believe that every time you write a character, you are advancing the stream position, so the next read attempts to read after the character you just wrote. This happens because your stream reader and stream writer are using the same FileStream. Use a different filestream, or seek -1 characters back in the stream after every write.

柠檬色的秋千 2024-10-02 11:15:18

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

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

It's highly unlikely that you'd be happy with any solution to this problem that involves using the same stream for reading and writing. That's especially true if you're trying to read the tail of the file using a StreamReader.

You want to have two different file streams. The writing stream can be a StreamWriter if you like. The reading stream should be a binary stream (i.e. create with File.OpenRead or FileStream.Create), read raw bytes from the file, and convert to text. My answer to this question shows the basics of how it's done.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文