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

时间:2011-08-26 11:30:22

标签: .net filesystems polling filesystemwatcher

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

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

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

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

我想知道是否存在此类问题的模式,或者是否有人遇到过这种情况。

3 个答案:

答案 0 :(得分: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);

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

此实现与每个POLL_TIME执行它的守护程序混合,对我们有效。希望它有所帮助。

答案 1 :(得分:1)

我最好的猜测是使用USN日志,如果它是本地机器,你有管理员权限,分区是NTFS。 USN期刊非常快速可靠。这是一个很长的topis,这个链接解释了一切: http://www.microsoft.com/msj/0999/journal/journal.aspx

答案 2 :(得分:0)

对于* nix环境,您可以使用inotify https://github.com/rvoicilas/inotify-tools/wiki/,这在我的有限研究中非常有用。可能有一个版本可以使用Windows,我没有经验...快速谷歌搜索引导我到一个名为jnotify http://jnotify.sourceforge.net/的java克隆,它被宣传为在Windows上工作,所以它可能值得尝试。 / p>