PutFile
/PutFileAsync
methods simply read blocks of data from a file stream until the Stream.Read
method returns zero, which indicates end of stream. During the process, each block is uploaded to the server and the byte counter is updated.
However, this can be problematic when a file that is being uploaded is currently opened by another process (or even the same process) and data is actually getting written to it while it's being uploaded. This is often the case with log files that keep slowly growing. To prevent transfer of files that are currently open for writing, try replacing a path-based PutFileAsync
call such as this:
long bytesTransferred = await ftp.PutFileAsync(localPath, remotePath);
With this:
long bytesTransferred;
using (var input = new FileStream(localPath, FileMode.Open, FileAccess.Read, FileShare.None))
{
bytesTransferred = await ftp.PutFileAsync(input, remotePath);
}
Another possible cause of the discrepancy is Sftp
object's TransferType
property. When it's set to SftpTransferType.Ascii
, and the ServerType
property is SftpServerType.Unix
, the SFTP client converts Windows end-of-line sequences (0D 0A) to Unix end-of-line sequences (0A), and each of these conversions decreeses the number of bytes transferred by one.
When you call Sftp.GetFileLength
after the file has been transferred, does the returned size match the number of bytes returned by PutFileAsync
?