文件流:如何对文件进行读写锁定

8
我有以下代码块,让我很头疼。
逻辑上来说,应该是可以工作的,因为我在使用文件流时提供了锁定。但是当它到达创建StreamWriter的那一行时,它失败并显示“文件不可写”。
现在我的程序是一个多线程应用程序。任何线程都可能尝试写入此文件。我需要程序锁定文件,读取内容,检查内容,然后写回任何更改。在该过程中,没有其他线程应该能够访问该文件。
using (var fs = File.Open(fileLoc, FileMode.Open, FileAccess.ReadWrite, FileShare.None))
{
    var sr = new StreamReader(fs);
    var str = sr.ReadToEnd();
    var strArray = str.Split(',');
    if (strArray.Any(st => st == text))
    {
        return;
    }
    sr.Close();

    var sw = new StreamWriter(fs);
    sw.Write(str + text);
    sw.Flush();
    sw.Close();
}
3个回答

10

FileShare.None标志不会导致线程排队,它只会锁定文件,因此会出现异常。为了提供互斥访问,您可以在写入之前锁定共享对象。

但是,你说:“现在我的程序是多线程应用程序。任何一个线程都可能试图写入这个文件。” 现在,这些线程是否都使用完全相同的方法来写入文件?假设它们是这样做的,那么这应该可以解决问题...

创建一个静态类变量...

private static object lockObject = new object();

在这里使用它...

lock (lockObject) 
{
    using(var sw = new StreamWriter(fs))
    {
       sw.Write(str + text);
    }
}

我对线程做了一些假设,所以如果这个方法不起作用或者需要更多的信息,请查阅有关同步的信息或向我们提供更多信息。

另外,在使用完StreamReader后,请及早关闭它(例如在方法返回之前)。立即在使用后关闭它,或者最好使用using



1

MSDN参考中所述,Close方法

关闭StreamReader对象和底层流,并释放与读取器相关联的任何系统资源。

因此,似乎后续对StreamWriter的调用未能使用已关闭的资源,导致出现“文件不可写”的消息。

请尝试这样做

            using (var fs = File.Open(path, FileMode.Open, FileAccess.ReadWrite, FileShare.None))
        {
            using (var sr = new StreamReader(fs))
            {
                var str = sr.ReadToEnd();
                // ...

                using (var sw = new StreamWriter(fs))
                {
                    // ...
                }
            }
        }

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