同时读写文件

时间:2012-07-24 08:46:47

标签: c# file

对于使用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个设备上运行

5 个答案:

答案 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.LockFileStream.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();
        }
    }
}

允许您传递一个函数,该函数将获取现有内容并生成新内容,并确保在发生此更改时,其他任何内容都不会读取或修改该文件