Monday, November 2, 2009

lock file in c#.net

In many projects or in many cases we need the file or folder to be locked or to stop the particular file deletion. In C#.net or in any other language we can achieve this using file reading.

How to prevent file deletion.
                  It is a simple method. In this method just open the file which we want to prevent from deletion. But do not close the open handler until we want to protect the file from deletion.

How to protect files from deleting C#.Net
                 The above simple method we can lock the file from deletion. To lock the file just open the file in FileStream. Do not close the file until we want to the file to be locked. the source code for locking the file is given below.
             

Source code:

using System;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using System.Threading;

namespace Consol
{
    ///


    /// A non-reentrant mutex that is implemented using
    /// a lock file, and thus works across processes,
    /// sessions, and machines (as long as the underlying
    /// FS provides robust r/w locking).
    ///
    /// To use:
    ///
    /// FileLock fLock = new FileLock(@"c:\foo\my.lock");
    ///
    /// using (fLock.Acquire())
    /// {
    ///        // protected operations
    /// }
    ///

    internal class LockFile
    {
        private readonly string filepath;
        private readonly DisposeHelper disposeHelper;
        private Stream stream;

        public LockFile(string filepath)
        {
            this.filepath = filepath;
            this.disposeHelper = new DisposeHelper(this);
        }

        public IDisposable Acquire()
        {
            string dir = Path.GetDirectoryName(filepath);

            lock (this)
            {
                while (stream != null)
                    Monitor.Wait(this);

                while (true)
                {
                    if (!Directory.Exists(dir))
                        Directory.CreateDirectory(dir);
                    try
                    {
                        Debug.Assert(stream == null, "Stream was not null--programmer error");
                        stream = new FileStream(filepath, FileMode.OpenOrCreate, FileAccess.Read, FileShare.None, 8, false);
                        return disposeHelper;
                    }
                    catch (IOException)
                    {
                        Thread.Sleep(500);
                        continue;
                    }
                }
            }
        }

        internal void Release()
        {
            lock (this)
            {
                Monitor.PulseAll(this);
                if (stream == null)
                    throw new InvalidOperationException("Tried to dispose a FileLock that was not owned");
                try
                {
                    stream.Close();
                    try
                    {
                        //File.Delete(filepath);
                    }
                    catch (IOException) { }
                }
                finally
                {
                    stream = null;
                }
            }
        }

        private class DisposeHelper : IDisposable
        {
            private readonly LockFile lockFile;

            public DisposeHelper(LockFile lockFile)
            {
                this.lockFile = lockFile;
            }

            public void Dispose()
            {
                lockFile.Release();
            }
        }
    }
}


Just add the above class. Create the object for the above class. then call object.acquire(filename). to release from locking call object.release().

Fav This With Technorati Add To Del.icio.us Digg This Add To Reddit

1 comments:

Anonymous said...

Just want to say what a great blog you got here!
I've been around for quite a lot of time, but finally decided to show my appreciation of your work!

Thumbs up, and keep it going!

Cheers
Christian, iwspo.net