我应该如何轮询大量文件以进行更改?

maf*_*afu 8 .net filesystems filesystemwatcher polling

我想在文件系统中轮询任何已更改,添加或删除的文件或子目录.应尽快检测所有更改,但不要对机器施加压力.操作系统是Windows> = Vista,观察到的部分是本地目录.

通常情况下,我会使用FileSystemWatcher,但这会导致其他程序试图查看相同位置的问题(突出显示,Windows资源管理器).另外,我听说FSW即使对于本地文件夹和大缓冲区也不是很可靠.

我遇到的主要问题是文件和目录的数量可能非常大(猜数为7位).只需每秒检查一次所有文件就会对我的机器造成明显影响.

我的下一个想法是每秒检查整棵树的不同部分以减少整体影响,并可能添加一种启发式方法,例如检查经常更快地更改的文件.

我想知道是否有这种问题的模式,或者是否有人有这种情况的经验.

Dan*_*lba 3

我们使用 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);
Run Code Online (Sandbox Code Playgroud)

我们所做的是静态处理。我们在磁盘上保存一棵元数据树,并将存储的目录树与加载的目录树进行比较,搜索修改的目录树(基于其时间戳(更快)或文件哈希)。此外,我们还可以管理删除、添加和移动,甚至移动修改的文件(也基于文件哈希)。

这个实现与每个 POLL_TIME 执行它的守护进程混合在一起,对我们来说是有效的。希望能帮助到你。