我有以下代码块让我头疼。
逻辑上它应该工作,因为我使用在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();
}
答案 0 :(得分:8)
FileShare.None标志不会导致线程排队,它只是锁定文件,因此会获得异常。要提供互斥访问,您可以在写入之前锁定共享对象。
但你说这个“现在我的程序是一个多线程应用程序。任何线程都可能试图写入这个文件。”现在,这些线程是否都使用完全相同的方法写入文件?我们假设他们这样做,那么这应该有用......
创建一个静态类变量......
private static object lockObject = new object();
在这里使用......
lock (lockObject)
{
using(var sw = new StreamWriter(fs))
{
sw.Write(str + text);
}
}
我已经对线程做了一些假设,所以如果这不起作用或者向我们提供更多信息,你可能需要查找有关同步的信息。
另外,请提前关闭StreamReader
(如果方法先前返回)。使用后立即关闭它,或者更好地使用using
。
答案 1 :(得分:3)
答案 2 :(得分:1)
与MSDN reference 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))
{
// ...
}
}
}