0 votes
by (180 points)

I am uploading files using the PutFileAsync for an sftp client. I get a response back with the number of bytes transferred does not match the size of the file being transferred. I do not get an exception or an error. Is there a way to know why the file did not fully transfer?

Applies to: Rebex SFTP

1 Answer

0 votes
by (147k points)

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?

...