Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there an equivalent to the .Net FileSystemWatcher in the Linux world?

I find the .Net FileSystemWatcher class really handy for writing utilities that automatically come to life when files show up in their watched folders. Is there any equivalent to this functionality in the *nix world that would allow me to watch a folder (and possibly all of its subdirectories)?

Edit: Preferably this will be something that doesn't require kernel patches.

like image 676
Luke Avatar asked Nov 27 '08 17:11

Luke


Video Answer


1 Answers

I would like to share my observations using FileSystemWatcher in Mono in Ubuntu 10.10. Here is a very simple implementation of FileSystemWatcher in C#

using System;
using System.Collections.Generic;
using System.Collections;
using System.Text;
using System.IO;
using System.Reflection;

namespace FileSystemWatcherSandbox
{
    public class Program
    {
        static void Main(string[] args)
        {
            foreach(DictionaryEntry de in Environment.GetEnvironmentVariables())
            {
                Console.WriteLine("{0} = {1}",de.Key,de.Value);
            }
            string basePath = AppDomain.CurrentDomain.BaseDirectory;
            Console.WriteLine("watching: {0}", basePath);
            FileSystemWatcher fsw = new FileSystemWatcher(basePath);
            fsw.Changed += new FileSystemEventHandler(fsw_Changed);
            fsw.Created += new FileSystemEventHandler(fsw_Created);
            fsw.Deleted += new FileSystemEventHandler(fsw_Deleted);
            fsw.Error += new ErrorEventHandler(fsw_Error);
            fsw.Renamed += new RenamedEventHandler(fsw_Renamed);
            fsw.EnableRaisingEvents = true;
            fsw.IncludeSubdirectories = true;
            while (true)
            {
                WaitForChangedResult result = fsw.WaitForChanged(WatcherChangeTypes.All,10000);
                Console.WriteLine(result.TimedOut ? "Time out" : "hmmm");
            }
        }

        static void fsw_Renamed(object sender, RenamedEventArgs e)
        {
            Console.WriteLine("({0}): {1} | {2}", MethodInfo.GetCurrentMethod().Name, e.ChangeType, e.FullPath);
        }

        static void fsw_Error(object sender, ErrorEventArgs e)
        {
            Console.WriteLine("({0}): {1}", MethodInfo.GetCurrentMethod().Name, e.GetException().Message);
        }

        static void fsw_Deleted(object sender, FileSystemEventArgs e)
        {
            Console.WriteLine("({0}): {1} | {2}", MethodInfo.GetCurrentMethod().Name, e.ChangeType, e.FullPath);
        }

        static void fsw_Created(object sender, FileSystemEventArgs e)
        {
            Console.WriteLine("({0}): {1} | {2}", MethodInfo.GetCurrentMethod().Name, e.ChangeType, e.FullPath);
        }

        static void fsw_Changed(object sender, FileSystemEventArgs e)
        {
            Console.WriteLine("({0}): {1} | {2}", MethodInfo.GetCurrentMethod().Name, e.ChangeType, e.FullPath);
        }
    }
}

This code was tested and works on both Windows XP and Ubuntu 10.10. However, I would like to point out that under Ubuntu 10.10 (possibly earlier versions as well), the FileSystemWatcher behaves uniquely.
If the directory that is being watched does not contain subdirectories, then invoking a FileSystemWatcher with the IncludeSubdirectories property set to true will result in the FileSystemWatcher ignoring events. However, if there are subdirectories in the target directory, then IncludeSubdirectories set to true will work as expected.
What will always work is if IncludeSubdirectories is set to false. In this instance, the FileSystemWatcher will only be watching the target directory.
I hope this is useful for programmers that would like to utilize Mono across different operating systems and invoke the FileSystemWatcher type.

like image 149
J Mills Avatar answered Oct 08 '22 15:10

J Mills