In C#, if 2 processes are reading and writing to the same file, what is the best way to avoid process locking exceptions?

前端 未结 8 1972
甜味超标
甜味超标 2020-12-13 04:25

With the following file reading code:

using (FileStream fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.None))
{
    using (T         


        
相关标签:
8条回答
  • 2020-12-13 05:01

    The reader and writer both need retry mechanisms. Also FileShare should be set to FileShare.read for the readers and FileShare.none for the writer. This should ensure that the readers don't read the file while writing is in progress.

    The reader (excluding retry) becomes

    using (FileStream fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read))
    {
        using (TextReader tr = new StreamReader(fileStream))
        {
            string fileContents = tr.ReadToEnd();
        }
    }
    

    The writer (excluding retry) becomes:

    FileStream fileStream = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.None);
    using (TextWriter tw = new StreamWriter(fileStream))
    {
        tw.Write(fileContents);
        tw.Close();
    }
    
    0 讨论(0)
  • 2020-12-13 05:03

    If you create a named Mutex you can define the mutex in the writing application, and have the reading application wait until the mutex is released.

    So in the notification process that is currently working with the FileSystemWatcher, simply check to see if you need to wait for the mutex, if you do, it will wait, then process.

    Here is a VB example of a Mutex like this that I found, it should be easy enough to convert to C#.

    0 讨论(0)
  • 2020-12-13 05:04

    You can open a file for writing and only lock write access, thereby allowing others to still read the file.

    For example,

    using (FileStream stream = new FileStream(@"C:\Myfile.txt", FileMode.Open, FileAccess.ReadWrite, FileShare.Read))
    {
       // Do your writing here.
    }
    

    Other file access just opens the file for reading and not writing, and allows readwrite sharing.

    using (FileStream stream = new FileStream(@"C:\Myfile.txt", FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
    {
       // Does reading  here.
    }
    

    If you want to ensure that readers will always read an up-to-date file, you will either need to use a locking file that indicates someone is writing to the file (though you may get a race condition if not carefully implemented) or make sure you block write-sharing when opening to read and handle the exception so you can try again until you get exclusive access.

    0 讨论(0)
  • 2020-12-13 05:05

    Get your process to check the status of the file if it is being written to. You can do this by the presence of a lock file (i.e. the presence of this other file, which can be empty, prevents writing to the main file).

    Even this is not failsafe however, as the two processes may create the lock file at the same time - but you can check for this before you commit the write.

    If your process encounters a lock file then get it to simply sleep/wait and try again at a predefined interval in the future.

    0 讨论(0)
  • 2020-12-13 05:07

    The best thing to do, is to put an application protocol on top of a file transfer/ownership transfer mechanism. The "lock-file" mechanism is an old UNIX hack that has been around for ages. The best thing to do, is to just "hand" the file over to the reader. There are lots of ways to do this. You can create the file with a random file name, and then "give" that name to the reader. That would allow the writer to asynchronously write another file. Think of how the "web page" works. A web page has a "link" to more information in it, for images, scripts, external content etc. The server hands you that page, because it's a coherent view of the "resource" you want. Your browser then goes and gets the appropriate content, based on what the page description (the HTML file or other returned content), and then transfers what it needs.

    This is the most resilient type of "sharing" mechanism to use. Write the file, share the name, move to the next file. The "sharing the name" part, is the atomic hand off that makes sure that both parties (the reader and the writer) agree that the content is "complete."

    0 讨论(0)
  • 2020-12-13 05:24

    Write to a temp file, when finished writing rename/move the file to the location and/or name that the reader is looking for.

    0 讨论(0)
提交回复
热议问题