private static void CopyFile(Stream source, string destination, int bytesPerChunk, IFileTransferHandler handler) { using (var br = new BinaryReader(source)) { using (var fsDest = new FileStream(destination, FileMode.Create)) { var bw = new BinaryWriter(fsDest); var buffer = new byte[bytesPerChunk]; int bytesRead; for (long i = 0; i < source.Length; i += bytesRead) { bytesRead = br.Read(buffer, 0, bytesPerChunk); bw.Write(buffer, 0, bytesRead); handler.IncrementBytesTransferred((ulong)bytesRead); } } } handler.TransferCompleted(); }
/// <exception cref="ArgumentNullException"><paramref name="path"/> is <b>null</b> or contains whitespace.</exception> /// <exception cref="ArgumentException"><paramref name="output"/> is <b>null</b>.</exception> /// <exception cref="SshConnectionException">Client not connected.</exception> private void InternalDownloadFile(string path, Stream output, IFileTransferHandler handler) { if (output == null) throw new ArgumentNullException("output"); if (path.IsNullOrWhiteSpace()) throw new ArgumentException("path"); // Ensure that connection is established. this.EnsureConnection(); var fullPath = this._sftpSession.GetCanonicalPath(path); var handle = this._sftpSession.RequestOpen(fullPath, Flags.Read); ulong offset = 0; var data = this._sftpSession.RequestRead(handle, offset, this.BufferSize); // Read data while available while (data.Length > 0) { output.Write(data, 0, data.Length); output.Flush(); offset += (ulong)data.Length; // Call callback to report number of bytes read if (handler != null) { handler.IncrementBytesTransferred((ulong)data.Length); } data = this._sftpSession.RequestRead(handle, offset, this.BufferSize); } this._sftpSession.RequestClose(handle); }
/// <summary> /// Performs SSH_FXP_WRITE request. /// </summary> /// <param name="handle">The handle.</param> /// <param name="offset">The offset.</param> /// <param name="data">The data to send.</param> /// <param name="wait">The wait event handle if needed.</param> /// <param name="handler">The object that handles callbacks for transferred data.</param> internal void RequestWrite(byte[] handle, UInt64 offset, byte[] data, EventWaitHandle wait, IFileTransferHandler handler) { var maximumDataSize = 1024 * 32 - 52; if (data.Length < maximumDataSize + 1) { var request = new SftpWriteRequest(this.NextRequestId, handle, offset, data, (response) => { if (response.StatusCode == StatusCodes.Ok) { if (wait != null) wait.Set(); if (handler != null) handler.IncrementBytesTransferred((ulong)data.Length); } else { this.ThrowSftpException(response); } }); this.SendRequest(request); if (wait != null) this.WaitHandle(wait, this._operationTimeout); } else { var block = data.Length / maximumDataSize + 1; for (int i = 0; i < block; i++) { var blockBufferSize = Math.Min(data.Length - maximumDataSize * i, maximumDataSize); var blockBuffer = new byte[blockBufferSize]; Buffer.BlockCopy(data, i * maximumDataSize, blockBuffer, 0, blockBufferSize); var request = new SftpWriteRequest(this.NextRequestId, handle, offset + (ulong)(i * maximumDataSize), blockBuffer, (response) => { if (response.StatusCode == StatusCodes.Ok) { if (wait != null) wait.Set(); if (handler != null) handler.IncrementBytesTransferred((ulong)blockBufferSize); } else { this.ThrowSftpException(response); } }); this.SendRequest(request); if (wait != null) this.WaitHandle(wait, this._operationTimeout); } } }