Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to manually Lock a file for other applications

I have spent quite some time figuring out how to do this but did not find any usefull solution.

Here is what I want to do. I am generating a huge binary file in my application. The tricky thing is that, the process requires me to occasionally close the FileStream. The problem now is, that occasionally other applications (i.e. my virus scanner) are using this brief moment where the file is not locked anymore, to lock the file itself. or other applications like dropbox etc...

The result is, that next time I need to open the file stream, it says that it is locked by another process. All this only happens very rarely but it is still annoying when it happens. And even if i still get the file access, I still don't want i.e. dropbox to upload this file until its done (which can take several minutes).

What I would need is a possibility to manually lock a file so that my application can still open file streams on this file, but no other application can until I manually unlock it again.

I picture something like this in pseudocode:

 File.Lock(filepath);

 //... do something that opens and closes filestreams on this file

 File.Unlock(filepath);

Is there a way to do this? The solution "keep the file stream open" is not valid. I explicitly try to avoid that so please keep that in mind.

like image 816
Oliver Bernhardt Avatar asked Nov 16 '12 18:11

Oliver Bernhardt


1 Answers

As you noticed yourself, the best way to lock a file is to open a handle to it using a FileStream. Your main FileStream gets closed, you say, but you can simulate a lock using one. Here's a sample class, using IDisposable so that the FileLock object itself is the lock, and disposing it releases it:

 public class FileLock : IDisposable
 {
    private FileStream _lock;
    public FileLock(string path)
    {
        if (File.Exists(path))
        {
            _lock = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.None);
            IsLocked = true;
        }            
    }

    public bool IsLocked { get; set; }

    public void Dispose()
    {
        if (_lock != null)
        {
            _lock.Dispose();
        }
    }
}

And usage:

using (FileLock lock = new FileLock(filePath))
{
      // Safe in the knowledge that the file is out of harm's way. 
}
like image 141
Avner Shahar-Kashtan Avatar answered Oct 27 '22 00:10

Avner Shahar-Kashtan