我必須觀察特定目錄中的特定文件結尾創建的新文件(例如:.txt)。如何可靠地觀察新創建文件的目錄?
這有考慮底層操作系統(Windows/Linux的)的工作,或者如果它是被訪問的NFS共享或Samba共享或本地目錄。
起初,我只用了FileSystemWatcher的
WatcherForPathToWatch_Created的watcherForPathToWatch = new FileSystemWatcher(folderToWatch, "*.rdy");
watcherForPathToWatch.Created += WatcherForPathToWatch_Created;
watcherForPathToWatch.Error += WatcherForPathToWatch_Error;
watcherForPathToWatch.IncludeSubdirectories = false;
watcherForPathToWatch.EnableRaisingEvents = true;
內容:
ThreadPool.QueueUserWorkItem(new WaitCallback(delegate { HandleFile(e.FullPath); }));
的問題是,它並沒有拿起所有文件。即使在NTFS分區上的本地目錄中,有時文件也沒有被處理。
所以,沒有考慮太多,我認爲做DirectoryEnumeration每隔幾分鐘就解決了我的問題。看起來這
private void EnumerationBasedArchiving()
{
watcherForPathToWatch.EnableRaisingEvents = false;
int maxThreads;
int unneeded;
int currThreads;
do
{
Thread.Sleep(500);
ThreadPool.GetMaxThreads(out maxThreads, out unneeded);
ThreadPool.GetAvailableThreads(out currThreads, out unneeded);
} while ((maxThreads - currThreads) != 0);
List<string> listOfFilesToArchive = null;
do
{
try
{
Directory.EnumerateFiles(folderToWatch, "*.txt", SearchOption.TopDirectoryOnly).ToList();
}
catch (Exception ex)
{
//error logging happens here, too
Thread.Sleep(10000);
}
} while (listOfFilesToArchive == null);
watcherForPathToWatch.EnableRaisingEvents = true;
Parallel.ForEach(listOfFilesToArchive, (fileToArchive) => { HandleFiles(fileToArchive); });
}
我用這種方法所的問題是,雖然它應該在大多數情況下工作,這不是太可靠。尤其是枚舉目錄內容和重新啓用處理程序之間的關鍵點。如果在這兩個點之間有一個文件被創建,我不會在下一個枚舉循環之前處理這個文件。
現在我想知道'最好'的解決方案是完全無視FileSystemWatcher,還是有辦法以某種方式使它更加可靠,因爲按照它們創建的順序來處理這些文件是非常重要的。
「,特別是點枚舉目錄的內容,然後再打開開關處理程序之間「 - 而不是切換處理程序,你可以在你的代碼中處理重複的通知? – Rup
我想。但是扔掉FileSystemWatcher的東西要容易得多。不知道爲什麼我沒有看到前面:/ –