I want to use FileSystemWatcher to monitor directory containing
log files, and parse them on changed. However, the bad person who wrote program creating logs, coded it so the log files are never actually closed. And though I can access them in FileShare.ReadWrite mode, the FileSystemWatcher actually never arises any events. So is there any walkaround for this issue?

Recommended Answers

All 2 Replies

I hesitated replying to this because I haven't actually used the FileSystemWatcher, though I am somewhat familiar with it. I'm a little confused what you are asking. Are you saying that when you change the file that FileSystemWatcher doesn't see the change, or are you wanting it to throw an exception if anybody other than the first instance having the file open attempts to access it in shared mode?

Posting some code so you can imitate the situation.
First class whereusing FileSystemWatcher

class Watcher
    {
        private FileSystemWatcher watcher;
        private string inputDirectoryPath;
        private string fileFilter = "*.txt";
        public Watcher(string _inputDirectoryPath)
        {
            inputDirectoryPath = _inputDirectoryPath;
            watcher = new FileSystemWatcher(inputDirectoryPath, fileFilter);
            watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite
               | NotifyFilters.FileName | NotifyFilters.DirectoryName;
            watcher.Changed += new FileSystemEventHandler(OnChanged);
            watcher.Deleted += new FileSystemEventHandler(OnChanged);
            watcher.Created += new FileSystemEventHandler(OnChanged);
            watcher.EnableRaisingEvents = true;
        }
        private void OnChanged(object source, FileSystemEventArgs e)
        {
            Console.WriteLine(e.FullPath + " " + e.ChangeType.ToString());
        }
    }

Second class that writes lines to file and close it only once.

class LockAndWriteFile
    {
        private bool isRunning = false;
        private string inputFilePath;
        public LockAndWriteFile(string _inputFilePath)
        {
            inputFilePath = _inputFilePath;
        }
        public void Start()
        {
            StreamWriter writer = null;
            try
            {
                writer = File.CreateText(inputFilePath);
                isRunning = true;
                while (isRunning)
                {
                    writer.WriteLine(DateTime.Now.ToString());
                    writer.Flush();
                    Thread.Sleep(1000);
                }
            }
            finally
            {
                writer.Close();
            }
        }
        public void Stop()
        {
            isRunning = false;
        }
    }

Third class that writes lines to file and closes it after each line appended.

class WriteFile
    {
        private bool isRunning = false;
        private string inputFilePath;
        public WriteFile(string _inputFilePath)
        {
            inputFilePath = _inputFilePath;
        }
        public void Start()
        {
            StreamWriter writer = null;
            try
            {

                isRunning = true;
                while (isRunning)
                {
                    try
                    {
                        FileInfo inputFileInfo = new FileInfo(inputFilePath);
                        if (inputFileInfo.Exists)
                        {
                            writer = File.AppendText(inputFilePath);
                        }
                        else
                        {
                            writer = File.CreateText(inputFilePath);
                        }
                        writer.WriteLine(DateTime.Now.ToString());
                    }
                    finally
                    {
                        writer.Close();
                    }
                    Thread.Sleep(1000);
                }
            }
            catch (Exception)
            { 
            }
        }
        public void Stop()
        {
            isRunning = false;
        }
    }

Finally the program to put it all together

class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Type q to stop the program");
            Watcher w = new Watcher("C:\\Temp");
            LockAndWriteFile l = new LockAndWriteFile("C:\\Temp\\1.txt");
            Thread t = new Thread(l.Start);
            t.Start();
            WriteFile wf = new WriteFile("C:\\Temp\\2.txt");
            Thread t1 = new Thread(wf.Start);
            t1.Start();         
            while (Console.Read() != 'q') ;
            l.Stop();
            wf.Stop();
        }
    }

If you run the program you will see that 2nd class raise FileSystemWatcher events only twice - on it creation and when it is finally closed. The question is, is it possible to do so that events will be raised actually after each modification, ie every time 2nd class calls flush method.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.