在Linux世界中是否有与.Net FileSystemWatcher等效的程序?

nkcskrwz  于 2023-01-20  发布在  Linux
关注(0)|答案(6)|浏览(196)

我发现.Net FileSystemWatcher类对于编写当文件显示在其监视的文件夹中时自动激活的实用程序非常方便。在 *nix世界中是否有任何与此功能等效的功能允许我监视一个文件夹(可能还有它的所有子目录)?

**编辑:**最好是不需要内核补丁。

watbbzwu

watbbzwu1#

我想分享一下我在Ubuntu 10.10中使用Mono中的FileSystemWatcher时的观察结果。下面是FileSystemWatcher在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);
        }
    }
}

这段代码在Windows XP和Ubuntu 10.10上都经过了测试,并且可以正常工作。但是,我想指出的是,在Ubuntu 10.10(可能还有更早的版本)下,FileSystemWatcher的行为是独一无二的。
如果正在监视的目录不包含子目录,则在IncludeSubdirectories属性设置为true的情况下调用FileSystemWatcher将导致FileSystemWatcher忽略事件。但是,如果目标目录中存在子目录,则IncludeSubdirectories设置为true将按预期工作。
如果IncludeSubdirectories设置为false,则始终有效。在这种情况下,FileSystemWatcher将只监视目标目录。
我希望这对希望跨不同操作系统使用Mono并调用FileSystemWatcher类型的程序员有用。

bzzcjhmw

bzzcjhmw2#

这将是Gamin the File Alteration MonitorInotify
编辑:Mono确实有Gamin绑定--事实上,它对FileSystemWatcher的实现使用了Gamin.https://www.mono-project.com/docs/faq/technical/#what-are-the-issues-with-filesystemwatcher。

FileSystemWatcher有什么问题?

FileSystemWatcher的Mono实现有许多后端,其中最佳的一个是inotify-backend(在Mono 1.1.17和更新版本中可用),它具有较少的依赖性。
有了这个后端,内核可以为Mono提供文件系统上文件的任何更改的更新,但它需要一个启用了inotify的内核,只有较新的Linux发行版才提供这种内核。
在较老的Linux系统中,您必须安装FAM或Gamin(它可以与任何一个一起工作),您可能需要安装-devel包。
对于 *BSD系列,有一个基于Kqueue的实现,当在运行时检测到时将使用该实现。
如果上述方法都不起作用,Mono福尔斯回退到轮询目录以查找更改,这远非最佳方法。

bqucvtff

bqucvtff3#

如前所述,Mono拥有类“System.IO.FileSystemWatcher”,这是相关链接:http://www.go-mono.com/docs/monodoc.ashx?link=T%3aSystem.IO.FileSystemWatcher
“Mono的FileSystemWatcher实现有多个后端。这是必要的,因为并非所有Mono支持的操作系统都具有提供应用程序所需功能的所有必要特性。
如果操作系统内核支持监视目录(Linux上的inotify、BSD或OSX上的KEvents),则使用该特性;否则,它福尔斯使用Gamin或FAM库(这些库提供了一个API来监视目录),如果这些功能都不可用,Mono将每750毫秒轮询一次所监视的目录。
您可以通过在执行应用程序之前设置MONO_MANAGED_WATCHER环境变量来强制轮询行为(而不是使用内核支持)。这对于不支持inotify但仍需要轮询来检测更改的文件系统可能很有用。”

n8ghc7c1

n8ghc7c14#

是的,数据通知和inotify
我不知道Mono有没有把这些包起来,但值得一查。

vsmadaxz

vsmadaxz5#

如果您使用的是优秀的QT库(www.qtsoftware.com),它作为QFileSystemWatcher包含在内。

ha5z0ras

ha5z0ras6#

我们还没有测试这在我们的情况下是否是一个合适的替代方案,但微软似乎在一段时间前就引入了PhysicalFileProvider。
它有一个UsePollingFileWatcher属性,专门针对这类问题。
然后对于文件监视,您似乎需要Watch方法。
文档目前显示它在某些平台或目标框架上不可用,但实际上the NuGet package声称与. NET Standard 2.0兼容,因此这应该基本上涵盖了所有内容。

相关问题