对于使用File作为某种公司设备预留的全局存储的应用程序,我需要一种方法来读取和写入文件(或锁定文件,从中读取,写入并解锁它)。一段代码片段会出现我的意思:
FileStream in = new FileStream("storage.bin", FileMode.Open);
//read the file
in.Close();
//!!!!!
//here is the critical section since between reading and writing, there shouldnt
//be a way for another process to access and lock the file, but there is the chance
//because the in stream is closed
//!!!!!
FileStream out = new FileStream("storage.bin", FileMode.Create);
//write data to file
out.Close();
这应该是这样的
LockFile("storage.bin");
//read from it...
//OVERwrite it....
UnlockFile("storage.bin");
该方法应该是绝对安全的,因为程序应该同时在2000个设备上运行
答案 0 :(得分:11)
仅使用独占(非共享)访问权限打开FileStream
将阻止其他进程访问该文件。这是打开文件进行读/写访问时的默认设置。
您可以通过截断它来“覆盖”当前保存的文件。
所以:
using (var file = File.Open("storage.bin", FileMode.Open))
{
// read from the file
file.SetLength(0); // truncate the file
// write to the file
}
该方法应该是绝对安全的,因为程序应该同时在2000个设备上运行
根据您写入文件的频率,这可能会成为一个阻塞点。您可能希望对此进行测试,以了解它的可扩展性。
此外,如果其中一个进程尝试同时对另一个进行操作,则会抛出IOException
。没有办法在文件上“等待”,因此您可能希望以更有序的方式协调文件访问。
答案 1 :(得分:3)
您需要一个单独的流,为阅读和写作打开。
FileStream fileStream = new FileStream(
@"c:\words.txt", FileMode.OpenOrCreate,
FileAccess.ReadWrite, FileShare.None);
或者您也可以尝试
static void Main(string[] args)
{
var text = File.ReadAllText(@"C:\words.txt");
File.WriteAllText(@"C:\words.txt", text + "DERP");
}
根据http://msdn.microsoft.com/en-us/library/system.io.fileshare(v=vs.71).aspx
FileStream s2 = new FileStream(name, FileMode.Open, FileAccess.Read, FileShare.None);
您需要传入FileShare枚举值None才能在FileStream构造函数重载上打开:
fs = new FileStream(@"C:\Users\Juan Luis\Desktop\corte.txt", FileMode.Open,
FileAccess.ReadWrite, FileShare.None);
答案 2 :(得分:1)
您可能正在寻找FileStream.Lock和FileStream.Unlock
答案 3 :(得分:1)
我认为你只需要在重载的Open方法中使用FileShare.None标志。
file = File.Open("storage.bin", FileMode.Open, FileShare.None);
答案 4 :(得分:1)
我最后编写了这个帮助程序类来执行此操作:
public static class FileHelper
{
public static void ReplaceFileContents(string fileName, Func<String, string> replacementFunction)
{
using (FileStream fileStream = new FileStream(
fileName, FileMode.OpenOrCreate,
FileAccess.ReadWrite, FileShare.None))
{
StreamReader streamReader = new StreamReader(fileStream);
string currentContents = streamReader.ReadToEnd();
var newContents = replacementFunction(currentContents);
fileStream.SetLength(0);
StreamWriter writer = new StreamWriter(fileStream);
writer.Write(newContents);
writer.Close();
}
}
}
允许您传递一个函数,该函数将获取现有内容并生成新内容,并确保在发生此更改时,其他任何内容都不会读取或修改该文件