使用TextWriter与StreamWriter同时进行读写操作

3
正如标题所示,我正在尝试同时读写文件。我已经研究了这个主题,但是我找到的答案似乎对我的程序不起作用,因为我的程序情况比较特殊。我使用多个FileSystemWatcher来跟踪大量通过网络流动的文件。随着文件通过流程的每个部分,一个文本文件被更新(每个流程中有一个文本文件),记录了文件的名称和创建时间。无法预测文件何时会通过,以及何时会写入跟踪文本文件。我的目标是能够同时读写文件,在用户尝试读取正在写入的文本文件时进行操作。我该如何实现这一点?
//Write to File
    private void WriteToFile(string info,string path,string tr)
    {
        if (!File.Exists(path+@"\"+@tr))
        {
            var myFile =
            File.Create(path + @"\" + @tr);
            myFile.Close();
            TextWriter tw = new StreamWriter(path + @"\" + @tr, true);
            tw.WriteLine(info,true);
            tw.Close();
        }
        else if (File.Exists(path + @"\" + @tr))
        {
            TextWriter tw = new StreamWriter(path + @"\" + @tr, true);
            tw.WriteLine(info);
            tw.Close();
        }
    }

请问您能否将负责读取文件的代码添加到您的问题中?谢谢! - Snoop
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Slai
1个回答

3
您提到的“情况”似乎表明,虽然可以在给定时间进行多次读/写文件的尝试,但您仍希望确保按照调用读取或写入的正确顺序一个接一个地执行操作。
为确保同步执行读取和写入操作,一种简单的方法是在方法周围放置锁或监视器。请尝试以下代码来编写您的写入方法:
private readonly object _locker = new object();

// write the file
private void WriteToFile(string info, string path, string tr)
{
    Monitor.Enter(this._locker);

    try
    {
        if (!File.Exists(path + @"\" + @tr))
        {
            var myFile =
            File.Create(path + @"\" + @tr);
            myFile.Close();
            TextWriter tw = new StreamWriter(path + @"\" + @tr, true);
            tw.WriteLine(info, true);
            tw.Close();
        }
        else if (File.Exists(path + @"\" + @tr))
        {
            TextWriter tw = new StreamWriter(path + @"\" + @tr, true);
            tw.WriteLine(info);
            tw.Close();
        }
    }
    finally
    {
        Monitor.Exit(this._locker);
    }
}

然后,我会使用非常相似的结构来读取文件。
// read the file
private string ReadFile(string path)
{
    Monitor.Enter(this._locker);

    try
    {
        // read the file here...
    }
    finally
    {
        Monitor.Exit(this._locker);
    }
}
< p > Monitor 的作用是确保在正在进行的write操作完成之前不会read文件(反之亦然)。这将确保您在读取文件时不会得到旧数据,并且您也不会覆盖尚未被读取的新数据。该方法始终验证文件的完整性。


这个是怎么工作的?如果我理解正确,它会“锁定”文件直到可以读/写?在阅读器中,我仍然只需要使用简单的文件流阅读器吗? - Marshal Alessi
@MarshalAlessi 实际上,它只是在对象上放置了一个锁。因此,在执行WriteFile时,方法ReadFile无法执行。实际上,您正在_locker对象上阻塞。换句话说,在任何给定时间内,只有一个线程可以通过Monitor,直到正在忙碌的线程到达Monitor.Exit()并愿意放弃锁定。这有意义吗? - Snoop
谢谢您的解释和回答!我还有一个问题,我刚刚测试了这个方法,但是它现在每个新文件产生四行数据,很奇怪。也就是说,当它写入文本文件时,它会将相同的行重复四次。这可能是什么原因呢? - Marshal Alessi
哇,我希望我没有逼迫你接受答案,哈哈。如果你选择了不同的答案,我也不会感到难过!好的,为了解决这个问题,我可能需要查看实际读取文件的代码。你能发一下吗? - Snoop
没关系,它能工作,所以我接受了它。我最初使用了一个简单的Streamreader行来ReadAllLines,但不得不为这个问题进行更改。问题来自于写入器,每次我发布一个新文件时,我查看物理文本文件,发现它会写入四行。例如,我在监视文件夹中发布了一个名为cavmsanass_Tracking.txt的文本文件,通常它会写入:1080\Auto\cavmsanass_Tracking.txt 6/19/2016 5:42:16 PM现在它写入:1080\Auto\cavmsanass_Tracking.txt 6/19/2016 5:42:16 PM,但重复了四次。 - Marshal Alessi
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接