8

我有以下代码块,这让我很头疼。

从逻辑上讲,它应该可以工作,因为我正在使用在 using 语句中提供锁的文件流。当它到达创建 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();
}
4

3 回答 3

10

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

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

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

private static object lockObject = new object();

在这里使用它...

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

我对线程做了一些假设,所以如果这不起作用,您可能需要查找有关同步的信息或向我们提供更多信息。

另外,请关闭您的StreamReader较早(以防该方法较早返回)。使用后立即关闭它,或者更好地使用using.

于 2012-12-04T15:31:09.460 回答
3

尝试线程同步。您可以从此链接找到更多详细信息

于 2012-12-04T08:21:03.283 回答
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))
                {
                    // ...
                }
            }
        }
于 2019-11-27T08:17:39.137 回答