Search code examples
c#.netsftpwinscpwinscp-net

How to download 10 newest files of type CSV via SFTP using WinSCP?


I use WinSCP quite basically from C#. For example I know that I can download several CSV files from an FTP site using this code:

var remotePath = "some\path*.csv";
var localPath = "some\path";
TransferOperationResult transferResult =
    session.GetFiles(remotePath, localPath, false, transferOptions);

But that downloads all the CSVs from the SFTP site. I only want the latest 10. I see from this link: https://winscp.net/eng/docs/script_download_most_recent_file how to get the latest file. And I have found using intellisense that there is a RemoteFileInfoCollection class.

But this class isn't very well documented (or at least not well enough for me to use)

Questions:

  1. How can I use this class?
  2. How can I request 'some' of the CSVs on an SFTP site using seesion.GetFiles(), since the remotePath param is a string and not a list. I know that I could loop through a list of paths and download those from the FTP, is that a reasonable approach? I'm not sure I'd want to call GetFiles() multiple times considering that it seems to specifically be named as file(s), and I know that it does download multiple files at once.

Solution

  • Use the code you have found to download the one latest file and just replace FirstOrDefault with Take and iterate the set to download all selected files.

    I'm also using EnumerateRemoteFiles instead of ListDirectory, as it can filter files by filemask on its own.

    const string remotePath = "/remote/path";
    const string localPath = "C:\local\path";
    
    IEnumerable<RemoteFileInfo> files =
        session.EnumerateRemoteFiles(remotePath, "*.csv", EnumerationOptions.None)
        .Where(file => !file.IsDirectory)
        .OrderByDescending(file => file.LastWriteTime)
        .Take(10);
    
    string destPath = Path.Combine(localPath, "*");
    foreach (RemoteFileInfo file in files)
    {
        Console.WriteLine("Downloading {0}...", file.Name);
        session.GetFiles(RemotePath.EscapeFileMask(file.FullName), destPath).Check();
    }