GNU/Linux >> Tutoriales Linux >  >> Linux

¿Existe un equivalente a .Net FileSystemWatcher en el mundo de Linux?

Como ya se ha dicho, Mono tiene la clase "System.IO.FileSystemWatcher", este es el enlace correspondiente:http://www.go-mono.com/docs/monodoc.ashx?link=T%3aSystem.IO. Vigilante del sistema de archivos

"La implementación de Mono de FileSystem Watcher tiene múltiples backends. Esto es necesario porque no todos los sistemas operativos compatibles con Mono tienen todas las características necesarias para proporcionar la funcionalidad esperada por las aplicaciones.

Si el kernel del sistema operativo admite la visualización de directorios (inotify en Linux, KEvents en BSD u OSX), se utiliza esa función; De lo contrario, recurre al uso de las bibliotecas Gamin o FAM (estas bibliotecas proporcionan una API para monitorear directorios) y si ninguna de esas funciones está disponible, Mono sondeará cada 750 milisegundos los directorios observados.

Puede forzar el comportamiento de sondeo (en lugar de usar el soporte del kernel) configurando la variable de entorno MONO_MANAGED_WATCHER antes de ejecutar su aplicación. Esto podría ser útil para los sistemas de archivos que no son compatibles con notify y aún requieren sondeo para detectar cambios".


Eso sería Gamin the File Alteration Monitor o Inotify.

Editar:Mono tiene enlaces Gamin; de hecho, su implementación de FileSystemWatcher usa Gamin. https://www.mono-project.com/docs/faq/technical/#what-are-the-issues-with-filesystemwatcher.

¿Cuáles son los problemas con FileSystemWatcher?

La implementación Mono de FileSystemWatcher tiene varios backends, el más óptimo, el que tiene menos dependencias es el inotify-backend (disponible en Mono 1.1.17 y versiones más recientes).

Con este backend, el kernel proporciona a Mono actualizaciones sobre cualquier cambio en los archivos en el sistema de archivos, pero requiere un kernel habilitado para inotify, que solo se envían las distribuciones de Linux más nuevas.

En sistemas Linux más antiguos, debe tener instalado FAM o Gamin (funcionará con cualquiera de los dos). Es posible que necesite los paquetes -devel instalados.

Para la familia *BSD, hay una implementación basada en Kqueue que se usará cuando se detecte en tiempo de ejecución.

Si nada de lo anterior funciona, Mono vuelve a sondear los directorios en busca de cambios, lo que dista mucho de ser óptimo.


Me gustaría compartir mis observaciones usando FileSystemWatcher en Mono en Ubuntu 10.10. Aquí hay una implementación muy simple de FileSystemWatcher en 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);
        }
    }
}

Este código fue probado y funciona tanto en Windows XP como en Ubuntu 10.10. Sin embargo, me gustaría señalar que en Ubuntu 10.10 (posiblemente también en versiones anteriores), FileSystemWatcher se comporta de manera única.
Si el directorio que se está supervisando no contiene subdirectorios, la invocación de FileSystemWatcher con la propiedad IncludeSubdirectories establecida en true hará que FileSystemWatcher ignore los eventos. Sin embargo, si hay subdirectorios en el directorio de destino, Incluir subdirectorios establecido en verdadero funcionará como se esperaba.
Lo que siempre funcionará es si Incluir subdirectorios se establece en falso. En este caso, FileSystemWatcher solo observará el directorio de destino.
Espero que esto sea útil para los programadores que deseen utilizar Mono en diferentes sistemas operativos e invocar el tipo FileSystemWatcher.


Linux
  1. Primeros pasos con el comando cat de Linux

  2. Fedora:¿hay un servicio de Ppa equivalente en el mundo de Fedora?

  3. ¿Hay STDCALL en Linux?

  4. ¿Existe un equivalente de Windows del comando de cadenas de Unix?

  5. ¿Cuál es el equivalente de ~ (tilde) de Linux en Windows?

Las 8 distribuciones de Linux más populares disponibles en el mercado

Un tipo de Windows en un mundo Linux:YaST y el escritorio

¿Cuál es el equivalente de Linux a la pausa de DOS?

Equivalente en Linux del comando de apertura de Mac OS X

¿Hay algún equivalente de WinSCP para Linux?

¿Cuál es el equivalente al comando de archivo de Linux para Windows?