FTP的FileSystemWatcher

dev*_*ull 11 .net c# ftp filesystemwatcher

如何实现FileSystemWatcherFTP位置(在C#中).这个想法是,无论何时在FTP位置添加任何内容,我都希望将其复制到本地计算机.任何想法都会有所帮助.

这是我之前使用.NET进行选择性FTP下载的问题的后续内容.

ang*_*son 16

您将不得不实施一个轮询解决方案,您可以定期询问目录内容.将此与前一次调用的缓存列表进行比较,并确定发生了什么.

不幸的是,FTP协议中没有任何内容可以帮助您解决这个问题.


Pau*_*ner 7

FileSystemWatcher班的工作方式与主机的Windows操作系统事件注册.因此,它仅限于在Windows系统上托管的目录的本地路径和UNC路径上工作.MSDN文档FileSystemWatcher说明了您可以使用的路径以及使用该类的一些潜在问题.

如果您希望收到有关FTP站点更改的警报,则必须使用轮询机制来询问您感兴趣监视的文件或文件夹的当前状态.通过比较FTP站点的快照以查看更改并在检测到更改时引发类似事件,您将能够查看何时添加和删除文件.不幸的是,您无法检测重命名事件,但其他更改应该很容易以这种方式进行监视.


Mar*_*ryl 6

您不能使用FileSystemWatcher或以任何其他方式,因为FTP协议没有任何API来通知客户端有关远程目录中的更改.

您所能做的就是定期迭代远程树并查找更改.

如果您使用支持远程树的递归列表的FTP客户端库,它实际上很容易实现.不幸的是,内置的.NET FTP客户端FtpWebRequest没有.但是,例如使用WinSCP .NET程序集版本5.9(或更新版本),您可以使用该Session.EnumerateRemoteFiles方法.

请参阅文章"查看SFTP/FTP服务器中的更改":

// Setup session options
SessionOptions sessionOptions = new SessionOptions
{
    Protocol = Protocol.Ftp,
    HostName = "example.com",
    UserName = "user",
    Password = "password",
};

using (Session session = new Session())
{
    // Connect
    session.Open(sessionOptions);

    List<string> prevFiles = null;

    while (true)
    {
        // Collect file list
        List<string> files =
            session.EnumerateRemoteFiles(
                "/remote/path", "*.*", EnumerationOptions.AllDirectories)
            .Select(fileInfo => fileInfo.FullName)
            .ToList();
        if (prevFiles == null)
        {
            // In the first round, just print number of files found
            Console.WriteLine("Found {0} files", files.Count);
        }
        else
        {
            // Then look for differences against the previous list
            IEnumerable<string> added = files.Except(prevFiles);
            if (added.Any())
            {
                Console.WriteLine("Added files:");
                foreach (string path in added)
                {
                    Console.WriteLine(path);
                }
            }

            IEnumerable<string> removed = prevFiles.Except(files);
            if (removed.Any())
            {
                Console.WriteLine("Removed files:");
                foreach (string path in removed)
                {
                    Console.WriteLine(path);
                }
            }
        }

        prevFiles = files;

        Console.WriteLine("Sleeping 10s...");
        Thread.Sleep(10000);
    }
}
Run Code Online (Sandbox Code Playgroud)

(我是WinSCP的作者)


但是,如果您确实只想下载更改,那么这样做会更容易.只需Session.SynchronizeDirectories在循环中使用.

session.SynchronizeDirectories(
    SynchronizationMode.Local, "/remote/path", @"C:\local\path", true).Check();
Run Code Online (Sandbox Code Playgroud)

如果您不想使用第三方库,则必须考虑到的限制FtpWebRequest.有关如何以递归方式列出远程目录树的示例FtpWebRequest,请参阅我对C#的回答通过FTP下载所有文件和子目录.