Dot-Net

Linux 世界中是否有與 .Net FileSystemWatcher 等價的東西?

  • August 16, 2020

我發現 .Net FileSystemWatcher 類對於編寫實用程序非常方便,這些實用程序會在文件出現在其監視的文件夾中時自動生效。*nix 世界中是否有任何與此功能等效的功能,可以讓我查看文件夾(可能還有它的所有子目錄)?

**編輯:**最好這將是不需要核心更新檔的東西。

那將是Gamin 文件更改監視器Inotify

編輯: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 會退回到輪詢目錄以進行更改,這遠非最佳。

我想在 Ubuntu 10.10 的 Mono 中使用 FileSystemWatcher 分享我的觀察。這是 C# 中 FileSystemWatcher 的一個非常簡單的實現

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 的行為是獨一無二的。

如果正在監視的目錄不包含子目錄,則呼叫 FileSystemWatcher 並將 IncludeSubdirectories 屬性設置為 true 將導致 FileSystemWatcher 忽略事件。但是,如果目標目錄中有子目錄,則將 IncludeSubdirectories 設置為 true 將按預期工作。

如果 IncludeSubdirectories 設置為 false,則始終有效。在這種情況下,FileSystemWatcher 將只監視目標目錄。

我希望這對希望跨不同作業系統使用 Mono 並呼叫 FileSystemWatcher 類型的程序員有用。

引用自:https://stackoverflow.com/questions/324258