File upload with WinSCP .NET/COM with temporary filenames

Arto Uusikangas picture Arto Uusikangas · Nov 20, 2014 · Viewed 7.7k times · Source

I am creating a small .NET application in C# to upload files to an FTP Server. I am using the .NET DLL for WinSCP while doing this and i have been trying to find a good solution to my problem.

The FTP folder where I will put all my files will be monitored by another application. This application will then take these files and process them automatically.

So what I want to avoid is that my files are grabbed by the application before the transfer is complete.

So I want to use either temporary filename usage or maybe a temporary folder and then move the files when upload is finished.

What do you suggest as the best approach? And second question is, in WinSCP .NET there should be an option for Transfer Resume that transfers the file with temporary name and renames when completed. But I cant seem to get this to work and are looking for any hints on how to get this to work?

Answer

Martin Prikryl picture Martin Prikryl · Nov 20, 2014

You are right that the "transfer to temporary file name" feature of WinSCP looks like the way to go.

It makes WinSCP upload file with the .filepart appended to its name, stripping the extension once done.

TransferOptions transferOptions = new TransferOptions();
transferOptions.ResumeSupport.State = TransferResumeSupportState.On;
session.PutFiles(@"d:\toupload\myfile.dat", "/home/user/", false, transferOptions).Check();

Though it is supported with an SFTP protocol only.


With an FTP protocol, you have to do this manually.

session.PutFiles(@"d:\toupload\myfile.dat", "/home/user/myfile.dat.filepart").Check();
session.MoveFile("/home/user/myfile.dat.filepart", "/home/user/myfile.dat");

If you are uploading multiple files, you can use an operation mask, and iterate list of successfully uploaded files returned by the Session.PutFiles in TransferOperationResult, calling the Session.MoveFile for each.

TransferOperationResult transferResult;
transferResult = session.PutFiles(@"d:\toupload\*.dat", "/home/user/*.filepart")

// Throw on any error
transferResult.Check();

// Rename uploaded files
foreach (TransferEventArgs transfer in transferResult.Transfers)
{
    string finalName = transfer.Destination.Replace(".filepart", ".dat");
    session.MoveFile(transfer.Destination, finalName);
}

There's also a complete PowerShell example in the article Locking files while uploading / Upload to temporary file name.


See also SFTP file lock mechanism (applies to FTP as well) for different approaches to hiding files being uploaded.