user6313890
user6313890

Reputation:

FileSystemWatcher.Changed on FTP

I want to use FileSystemWatcher.Changed on a FTP directory

What do I put in the property FileSystemWatcher.Path ?

Upvotes: 1

Views: 1233

Answers (2)

Martin Prikryl
Martin Prikryl

Reputation: 202474

You cannot use the FileSystemWatcher or any other way, because the FTP protocol does not have any API to notify a client about changes in the remote directory.

All you can do its to periodically iterate the remote tree and find changes.

It's actually rather easy to implement, if you use an FTP client that supports recursive listing of a remote tree. Unfortunately, the build-in .NET FTP client, the FtpWebRequest does not. For example with WinSCP .NET assembly, you can use the Session.EnumerateRemoteFiles method.

See the article Watching for changes in SFTP/FTP server:

// 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);
    }
}

(I'm the author of WinSCP)


Though, if you actually want to just download the changes, it's a way easier. Just use the Session.SynchronizeDirectories in the loop.

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

If you do not want to use a 3rd party library, you have to do with limitations of the FtpWebRequest. For an example how to recursively list a remote directory tree with the FtpWebRequest, see my answer to C# Download all files and subdirectories through FTP.

Upvotes: 1

Peter Keuter
Peter Keuter

Reputation: 788

You can not do this. A FileSystemWatcher watches the filesystem, not an FTP-folder. So unless you have filesystem access to the FTP-path (UNC paths are supported), you are unable to do this.

Upvotes: 1

Related Questions