I recommend the approach demonstrated by the code below. The approach uploads files to a temporary folder, moving each file to the final folder when it is successfully transferred. It also cleans temporary folder (structure) afterwords.
// holds list of path which failed to transfer
List<string> _failed = new List<string>();
// holds list of temporary created folders
List<string> _createdFolders = new List<string>();
string sourcePath = @"c:\temp\extracted\*.txt";
string tempFolder = "/home/tester0/upload/temp";
string finalFolder = "/home/tester0/upload/final";
public void Run()
{
using (Sftp client = new Sftp())
{
// connect and login
client.Connect("server");
client.Login("user", "pass");
// register batch events
client.BatchTransferProgress += new SftpBatchTransferProgressEventHandler(client_BatchTransferProgress);
client.BatchTransferProblemDetected += new SftpBatchTransferProblemDetectedEventHandler(client_BatchTransferProblemDetected);
// create temporary folder for files to upload
if (!client.DirectoryExists(tempFolder))
{
client.CreateDirectory(tempFolder);
_createdFolders.Add(tempFolder);
}
// create final folder for files to upload
if (!client.DirectoryExists(finalFolder))
client.CreateDirectory(finalFolder);
// upload files in XCopy mode overwriting all existing files
client.PutFiles(sourcePath, tempFolder, SftpBatchTransferOptions.XCopy, SftpActionOnExistingFiles.OverwriteAll);
// remove temporary folder structure (from the end)
for (int i = _createdFolders.Count-1; i >= 0; i--)
{
client.RemoveDirectory(_createdFolders[i]);
}
}
// report failed files
if (_failed.Count > 0)
{
Console.WriteLine("Following file(s) failed to transfer:");
foreach (string path in _failed)
{
Console.WriteLine(path);
}
}
}
void client_BatchTransferProgress(object sender, SftpBatchTransferProgressEventArgs e)
{
// get Sftp client object
Sftp client = (Sftp)sender;
// prepare final path
string finalPath = finalFolder + e.RemotePath.Substring(tempFolder.Length);
switch (e.Operation)
{
case SftpBatchTransferOperation.DirectoryCreated:
// batch operation created folder, store it for the clean up
_createdFolders.Add(e.RemotePath);
break;
case SftpBatchTransferOperation.DirectoryProcessingStarted:
// create final folder
if (!client.DirectoryExists(finalPath))
client.CreateDirectory(finalPath);
break;
case SftpBatchTransferOperation.FileTransferred:
// delete the file if it already exists in target destination
if (client.FileExists(finalPath))
client.DeleteFile(finalPath);
// move/rename successfully transferred file
client.Rename(e.RemotePath, finalPath);
break;
}
}
void client_BatchTransferProblemDetected(object sender, SftpBatchTransferProblemDetectedEventArgs e)
{
// ignore FileExists problem (use default behaviour)
if (e.ProblemType == SftpBatchTransferProblemType.FileExists)
return;
// store path of the failed transfer
_failed.Add(e.LocalPath);
e.Action = SftpBatchTransferAction.Skip;
}