我有一个小的csv文件,每个文件大约有40行,每行30个字符。我也有几个慢线程同时进行,所以他们很少会同时尝试访问该文件,但它可能会发生。所以我需要确保他们都在必要时等待转弯。
据我所知,我能做到:
string[] text = File.ReadAllLines(path);
text[23] = "replacement";
File.WriteAllLines(path, text);
但是这样做我假设我冒着文件被readAllLines和WriteAllLines之间的另一个线程更新的风险。
我想做的是:
using (FileStream fs = File.Open(filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite))
{
StreamReader sr = new StreamReader(fs);
StreamWriter sw = new StreamWriter(fs);
//Replace the line
}
但是,我没有看到使用FileStream对象或StreamWriter对象执行writeAllLines之类的方法。有没有一种简单的方法可以做到这一点,或者我是否需要将每一行写入新文件然后替换旧文件?
答案 0 :(得分:3)
使用StreamWriter
,您无需指定写入所有行。你只需写下自己拥有的东西。使用WriteLine
方法逐行写入文件,或者将文本数组连接成一个大字符串,然后使用Write
方法一次性写入。
至于防止多个线程同时访问您的文件,您应该使用锁。
public static object FileAccessLock = new object(); // Put this in a global area.
lock(FileAccessLock)
{
string[] text = File.ReadAllLines(path);
text[23] = "replacement";
File.WriteAllLines(path, text);
}
锁只允许一个线程一次访问该段代码。所有其他线程将一直等到它完成。
这并不意味着File.WriteAllLines
方法不会被别的东西锁定,所以你应该在这里处理一个异常。
答案 1 :(得分:1)
您需要仅对一个线程访问锁定写入。 像这样:
public class FileHelper
{
private static object fileLock = new object();
public static void ReplaceLine(string path, int line, string replace)
{
lock(fileLock)
{
string[] text = File.ReadAllLines(path);
text[line] = replace;
File.WriteAllLines(path, text);
}
}
}