我要观察一个特定目录,以查找使用特定文件结尾创建的新文件(例如:.txt)。
无论底层操作系统(Windows / Linux)如何,或者它是正在访问的NFS共享,还是Samba共享或本地目录,都必须工作。
起初我只使用了FileSystemWatcher
watcherForPathToWatch = new FileSystemWatcher(folderToWatch, "*.rdy");
watcherForPathToWatch.Created += WatcherForPathToWatch_Created;
watcherForPathToWatch.Error += WatcherForPathToWatch_Error;
watcherForPathToWatch.IncludeSubdirectories = false;
watcherForPathToWatch.EnableRaisingEvents = true;
WatcherForPathToWatch_Created的内容:
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,还是有办法以某种方式使其更可靠,因为按照创建顺序处理这些文件非常重要。
答案 0 :(得分:1)
Linux described here上有inotify
,但你不会得到任何涵盖Windows和Linux以及NFS和Samba的东西,所以你可能会最终滚动你自己的} EM>
只是一个想法..你说按照创建顺序处理文件很重要...好吧,因为你可能会发现文件处于“错误”的顺序,并不一定会妨碍你处理它们按正确的顺序 - 因为每个文件都有一个时间戳,因此您可以按照与查找顺序不同的顺序处理它们。当然,这可能涉及在您找到它们和实际处理它们之间编码延迟,但是如果您的轮询间隔设置正确...