我们使用C#实现了一个类似的功能。对于大型目录树,FileSystemWatcher效率不高。
我们的选择,使用FSNodes
,由我们创造的结构,使用下面的Windows API调用:
[StructLayout(LayoutKind.Sequential)]
private struct FILETIME
{
public uint dwLowDateTime;
public uint dwHighDateTime;
};
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
private struct WIN32_FIND_DATA
{
public FileAttributes dwFileAttributes;
public FILETIME ftCreationTime;
public FILETIME ftLastAccessTime;
public FILETIME ftLastWriteTime;
public uint nFileSizeHigh;
public uint nFileSizeLow;
public int dwReserved0;
public int dwReserved1;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=MAX_PATH)]
public string cFileName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=MAX_ALTERNATE)]
public string cAlternate;
}
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool FindClose(IntPtr hFindFile);
[DllImport("kernel32", CharSet=CharSet.Unicode)]
private static extern IntPtr FindFirstFile(
string lpFileName, out WIN32_FIND_DATA lpFindFileData);
[DllImport("kernel32", CharSet=CharSet.Unicode)]
private static extern bool FindNextFile(
IntPtr hFindFile, out WIN32_FIND_DATA lpFindFileData);
我们做的是一个静态的处理。我们将一个元数据树保存在磁盘上,并比较存储的目录树与加载的目录树,搜索修改(基于其时间戳(更快)或文件散列)。此外,我们可以管理删除,添加和移动,甚至移动修改的文件(也基于文件哈希)。
这个实现和守护进程混合在一起,每个守护进程都执行它,每个POLL_TIME对我们都有效。希望能帮助到你。
所有子文件夹是否在单个根目录下?你有什么样的问题与Windows资源管理器?这里有一个模式可以确保你不会错过任何消息。 http://stackoverflow.com/questions/4967095/c-predict-file-system-events-on-folder-delete/4968391#4968391 – adrianm
@adrianm:是的,同一根。 ---当受监控的文件夹发生变化时,Explorer没有更新其视图,我想因为FSW偷走了它的事件。 – mafu