tags:

views:

67

answers:

2

I am developing an application in C# (.NET), and am having trouble dealing with file locking.

  • My main application (A) needs read/write access to a certain file.
  • A separate application (B) needs read access to the same file.
  • I need to prevent the user from editing or deleting the file while my application (A) is running. The application (A) is long-running. The file must not be deleted while (A) is running, even when it is not actively being read from or written to.

I have full control of the source of (A) and (B), so I can modify either of them.

How can I stop a user from modifying/deleting a file while application (A) is running, while allowing application (A) to read/write, and application (B) to read?

A: 

though I have not used it, but named Mutex can save your day. Before opening a file in application A, create a mutext like this:

Mutex(bool initiallyOwned, string name, out bool createdNew)

pass file name as second parameter.

now when you open a file in application B, again use Mutex if out parameter createdNew is false then file is already opened by A so you can only read it.

TheVillageIdiot
How will this prevent a user from deleting the file, say, through Windows Explorer?
Joviee
@Joviee if you have opened file exclusively then it will pervent other processes from deleting it, but then it might crop up other issues like other processes not even able to read it. This will work only in your two (or future) applications and cannot stop someone using explorer, command line etc to delete file.
TheVillageIdiot
+2  A: 

Use FileShare.Read to only allow reads from other applications. You can lock the file by having a stream open while the application A runs. You need a NonClosingStreamWrapper to avoid disposing the stream when you dispose your StreamWriter (this happens automatically with using)

NonClosingStreamWrapper by Jon Skeet can be found from here

Example

When application starts use this to lock the file

FileStream fileStream = new FileStream(file, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.Read);

When writing to a file use

using (StreamWriter sr = new StreamWriter(new NonClosingStreamWrapper(fileStream)))
{
    // File writing as usual
}

When application ends use this to release the file

fileStream.Close();
Cloudanger
This solves my problem. Something to note, however, is that StreamWriter will close the underlying stream (and thus unlock the file) when it is disposed, so you have to work around that. I've been using NonClosingStreamWrapper from Jon Skeet's MiscUtils.
Joviee
@Joviee Thanks. The answer is now edited to note those things you said.
Cloudanger