If you are using single-file operations GetFile
or PutFile
you can specify target path as argument.
Unfortunately, there is no direct support for this in multi-file operations Upload
or Download
, but it can be done using the TransferProgressChanged
event like this:
client.TransferProgressChanged += (s, e) =>
{
if (e.TransferState == TransferProgressState.FileTransferred)
{
string extension = Path.GetExtension(e.TargetPath);
string pathWithoutExtension = e.TargetPath.Substring(0, e.TargetPath.Length-extension.Length);
string timestamp = e.SourceItem.LastWriteTime.GetValueOrDefault().ToString("-yyyyMMdd-HHmmss");
string newPath = string.Format("{0}{1}{2}", pathWithoutExtension, timestamp, extension);
Console.WriteLine("Moving: {0} -> {1}", e.TargetPath, newPath);
if (e.Action == TransferAction.Downloading)
{
if (File.Exists(newPath))
File.Delete(newPath);
File.Move(e.TargetPath, newPath);
}
else if(e.Action == TransferAction.Uploading)
{
// This is only possible for SFTP, which supports multiple operations to be executed at once.
// For FTP, files has to be renamed after the whole Upload operation is finished.
if (client.FileExists(newPath))
client.Delete(newPath, TraversalMode.NonRecursive);
client.Rename(e.TargetPath, newPath);
}
}
};
If the above solution is not possible for any reason, you can do it in two steps.
- Get list of all items. For download use
client.GetItems()
method. For upload use FileSet.GetLocalItems() method.
- Iterate through all items and transfer them using single-file operation with appropriate name+timestamp argument.