private void InternalDownloadFile(string path, Stream output, SftpDownloadAsyncResult asyncResult, Action<ulong> downloadCallback)
{
if (output == null)
throw new ArgumentNullException("output");
if (path.IsNullOrWhiteSpace())
throw new ArgumentException("path");
if (_sftpSession == null)
throw new SshConnectionException("Client not connected.");
var fullPath = _sftpSession.GetCanonicalPath(path);
var handle = _sftpSession.RequestOpen(fullPath, Flags.Read);
ulong offset = 0;
var optimalReadLength = _sftpSession.CalculateOptimalReadLength(_bufferSize);
var data = _sftpSession.RequestRead(handle, offset, optimalReadLength);
// Read data while available
while (data.Length > 0)
{
// Cancel download
if (asyncResult != null && asyncResult.IsDownloadCanceled)
break;
output.Write(data, 0, data.Length);
output.Flush();
offset += (ulong)data.Length;
// Call callback to report number of bytes read
if (downloadCallback != null)
{
// copy offset to ensure it's not modified between now and execution of callback
var downloadOffset = offset;
// Execute callback on different thread
ThreadAbstraction.ExecuteThread(() => { downloadCallback(downloadOffset); });
}
data = _sftpSession.RequestRead(handle, offset, optimalReadLength);
}
_sftpSession.RequestClose(handle);
}