|  | @@ -18,9 +18,9 @@ namespace Renci.SshNet.Sftp
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          // Buffer information.
 | 
	
		
			
				|  |  |          private readonly int _readBufferSize;
 | 
	
		
			
				|  |  | -        private readonly byte[] _readBuffer;
 | 
	
		
			
				|  |  | +        private byte[] _readBuffer;
 | 
	
		
			
				|  |  |          private readonly int _writeBufferSize;
 | 
	
		
			
				|  |  | -        private readonly byte[] _writeBuffer;
 | 
	
		
			
				|  |  | +        private byte[] _writeBuffer;
 | 
	
		
			
				|  |  |          private int _bufferPosition;
 | 
	
		
			
				|  |  |          private int _bufferLen;
 | 
	
		
			
				|  |  |          private long _position;
 | 
	
	
		
			
				|  | @@ -28,7 +28,6 @@ namespace Renci.SshNet.Sftp
 | 
	
		
			
				|  |  |          private bool _canRead;
 | 
	
		
			
				|  |  |          private bool _canSeek;
 | 
	
		
			
				|  |  |          private bool _canWrite;
 | 
	
		
			
				|  |  | -        private ulong _serverFilePosition;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          private readonly object _lock = new object();
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -254,15 +253,12 @@ namespace Renci.SshNet.Sftp
 | 
	
		
			
				|  |  |              // or SSH_FXP_WRITE message
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |              _readBufferSize = (int) session.CalculateOptimalReadLength((uint) bufferSize);
 | 
	
		
			
				|  |  | -            _readBuffer = new byte[_readBufferSize];
 | 
	
		
			
				|  |  |              _writeBufferSize = (int) session.CalculateOptimalWriteLength((uint) bufferSize, _handle);
 | 
	
		
			
				|  |  | -            _writeBuffer = new byte[_writeBufferSize];
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |              if (mode == FileMode.Append)
 | 
	
		
			
				|  |  |              {
 | 
	
		
			
				|  |  |                  var attributes = _session.RequestFStat(_handle, false);
 | 
	
		
			
				|  |  |                  _position = attributes.Size;
 | 
	
		
			
				|  |  | -                _serverFilePosition = (ulong) attributes.Size;
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -314,6 +310,22 @@ namespace Renci.SshNet.Sftp
 | 
	
		
			
				|  |  |          /// <exception cref="IOException">An I/O error occurs. </exception>
 | 
	
		
			
				|  |  |          /// <exception cref="NotSupportedException">The stream does not support reading. </exception>
 | 
	
		
			
				|  |  |          /// <exception cref="ObjectDisposedException">Methods were called after the stream was closed. </exception>
 | 
	
		
			
				|  |  | +        /// <remarks>
 | 
	
		
			
				|  |  | +        /// <para>
 | 
	
		
			
				|  |  | +        /// This method attempts to read up to <paramref name="count"/> bytes. This either from the buffer, from the
 | 
	
		
			
				|  |  | +        /// server (using one or more <c>SSH_FXP_READ</c> requests) or using a combination of both.
 | 
	
		
			
				|  |  | +        /// </para>
 | 
	
		
			
				|  |  | +        /// <para>
 | 
	
		
			
				|  |  | +        /// The read loop is interrupted when either <paramref name="count"/> bytes are read, the server returns zero
 | 
	
		
			
				|  |  | +        /// bytes (EOF) or less bytes than the read buffer size.
 | 
	
		
			
				|  |  | +        /// </para>
 | 
	
		
			
				|  |  | +        /// <para>
 | 
	
		
			
				|  |  | +        /// When a server returns less number of bytes than the read buffer size, this <c>may</c> indicate that EOF has
 | 
	
		
			
				|  |  | +        /// been reached. A subsequent (<c>SSH_FXP_READ</c>) server request is necessary to make sure EOF has effectively
 | 
	
		
			
				|  |  | +        /// been reached.  Breaking out of the read loop avoids reading from the server twice to determine EOF: once in
 | 
	
		
			
				|  |  | +        /// the read loop, and once upon the next <see cref="Read"/> or <see cref="ReadByte"/> invocation.
 | 
	
		
			
				|  |  | +        /// </para>
 | 
	
		
			
				|  |  | +        /// </remarks>
 | 
	
		
			
				|  |  |          public override int Read(byte[] buffer, int offset, int count)
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  |              var readLen = 0;
 | 
	
	
		
			
				|  | @@ -342,60 +354,82 @@ namespace Renci.SshNet.Sftp
 | 
	
		
			
				|  |  |                      var bytesAvailableInBuffer = _bufferLen - _bufferPosition;
 | 
	
		
			
				|  |  |                      if (bytesAvailableInBuffer <= 0)
 | 
	
		
			
				|  |  |                      {
 | 
	
		
			
				|  |  | -                        _bufferPosition = 0;
 | 
	
		
			
				|  |  | -                        _bufferLen = 0;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |                          var data = _session.RequestRead(_handle, (ulong) _position, (uint) _readBufferSize);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -                        // TODO: don't we need to take into account the number of bytes read (data.Length) ?
 | 
	
		
			
				|  |  | -                        _serverFilePosition = (ulong) _position;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |                          if (data.Length == 0)
 | 
	
		
			
				|  |  |                          {
 | 
	
		
			
				|  |  | +                            _bufferPosition = 0;
 | 
	
		
			
				|  |  | +                            _bufferLen = 0;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |                              break;
 | 
	
		
			
				|  |  |                          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -                        // determine number of bytes that we can read into caller-provided buffer
 | 
	
		
			
				|  |  | -                        var bytesToWriteToCallerBuffer = Math.Min(data.Length, count);
 | 
	
		
			
				|  |  | +                        var bytesToWriteToCallerBuffer = count;
 | 
	
		
			
				|  |  | +                        if (bytesToWriteToCallerBuffer >= data.Length)
 | 
	
		
			
				|  |  | +                        {
 | 
	
		
			
				|  |  | +                            // write all data read to caller-provided buffer
 | 
	
		
			
				|  |  | +                            bytesToWriteToCallerBuffer = data.Length;
 | 
	
		
			
				|  |  | +                            // reset buffer since we will skip buffering
 | 
	
		
			
				|  |  | +                            _bufferPosition = 0;
 | 
	
		
			
				|  |  | +                            _bufferLen = 0;
 | 
	
		
			
				|  |  | +                        }
 | 
	
		
			
				|  |  | +                        else
 | 
	
		
			
				|  |  | +                        {
 | 
	
		
			
				|  |  | +                            // determine number of bytes that we should write into read buffer
 | 
	
		
			
				|  |  | +                            var bytesToWriteToReadBuffer = data.Length - bytesToWriteToCallerBuffer;
 | 
	
		
			
				|  |  | +                            // write remaining bytes to read buffer
 | 
	
		
			
				|  |  | +                            Buffer.BlockCopy(data, count, GetOrCreateReadBuffer(), 0, bytesToWriteToReadBuffer);
 | 
	
		
			
				|  |  | +                            // update position in read buffer
 | 
	
		
			
				|  |  | +                            _bufferPosition = 0;
 | 
	
		
			
				|  |  | +                            // update number of bytes in read buffer
 | 
	
		
			
				|  |  | +                            _bufferLen = bytesToWriteToReadBuffer;
 | 
	
		
			
				|  |  | +                        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |                          // write bytes to caller-provided buffer
 | 
	
		
			
				|  |  |                          Buffer.BlockCopy(data, 0, buffer, offset, bytesToWriteToCallerBuffer);
 | 
	
		
			
				|  |  | -                        // advance offset to start writing bytes into caller-provided buffer
 | 
	
		
			
				|  |  | -                        offset += bytesToWriteToCallerBuffer;
 | 
	
		
			
				|  |  | -                        // update number of bytes left to read
 | 
	
		
			
				|  |  | -                        count -= bytesToWriteToCallerBuffer;
 | 
	
		
			
				|  |  | -                        // record total number of bytes read into caller-provided buffer
 | 
	
		
			
				|  |  | -                        readLen += bytesToWriteToCallerBuffer;
 | 
	
		
			
				|  |  |                          // update stream position
 | 
	
		
			
				|  |  |                          _position += bytesToWriteToCallerBuffer;
 | 
	
		
			
				|  |  | +                        // record total number of bytes read into caller-provided buffer
 | 
	
		
			
				|  |  | +                        readLen += bytesToWriteToCallerBuffer;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -                        if (data.Length > bytesToWriteToCallerBuffer)
 | 
	
		
			
				|  |  | +                        // break out of the read loop when the server returned less than the request number of bytes
 | 
	
		
			
				|  |  | +                        // as that *may* indicate that we've reached EOF
 | 
	
		
			
				|  |  | +                        //
 | 
	
		
			
				|  |  | +                        // doing this avoids reading from server twice to determine EOF: once in the read loop, and
 | 
	
		
			
				|  |  | +                        // once upon the next Read or ReadByte invocation by the caller
 | 
	
		
			
				|  |  | +                        if (data.Length < _readBufferSize)
 | 
	
		
			
				|  |  |                          {
 | 
	
		
			
				|  |  | -                            // copy remaining bytes to read buffer
 | 
	
		
			
				|  |  | -                            _bufferLen = data.Length - bytesToWriteToCallerBuffer;
 | 
	
		
			
				|  |  | -                            Buffer.BlockCopy(data, bytesToWriteToCallerBuffer, _readBuffer, 0, _bufferLen);
 | 
	
		
			
				|  |  | +                            break;
 | 
	
		
			
				|  |  |                          }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                        // advance offset to start writing bytes into caller-provided buffer
 | 
	
		
			
				|  |  | +                        offset += bytesToWriteToCallerBuffer;
 | 
	
		
			
				|  |  | +                        // update number of bytes left to read into caller-provided buffer
 | 
	
		
			
				|  |  | +                        count -= bytesToWriteToCallerBuffer;
 | 
	
		
			
				|  |  |                      }
 | 
	
		
			
				|  |  |                      else
 | 
	
		
			
				|  |  |                      {
 | 
	
		
			
				|  |  | -                        // determine number of bytes that we can write from read buffer to caller-provided buffer
 | 
	
		
			
				|  |  | -                        var bytesToWriteToCallerBuffer = Math.Min(bytesAvailableInBuffer, count);
 | 
	
		
			
				|  |  | +                        // limit the number of bytes to use from read buffer to the caller-request number of bytes
 | 
	
		
			
				|  |  | +                        if (bytesAvailableInBuffer > count)
 | 
	
		
			
				|  |  | +                            bytesAvailableInBuffer = count;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |                          // copy data from read buffer to the caller-provided buffer
 | 
	
		
			
				|  |  | -                        Buffer.BlockCopy(_readBuffer, _bufferPosition, buffer, offset, bytesToWriteToCallerBuffer);
 | 
	
		
			
				|  |  | +                        Buffer.BlockCopy(GetOrCreateReadBuffer(), _bufferPosition, buffer, offset, bytesAvailableInBuffer);
 | 
	
		
			
				|  |  |                          // update position in read buffer
 | 
	
		
			
				|  |  | -                        _bufferPosition += bytesToWriteToCallerBuffer;
 | 
	
		
			
				|  |  | +                        _bufferPosition += bytesAvailableInBuffer;
 | 
	
		
			
				|  |  | +                        // update stream position
 | 
	
		
			
				|  |  | +                        _position += bytesAvailableInBuffer;
 | 
	
		
			
				|  |  | +                        // record total number of bytes read into caller-provided buffer
 | 
	
		
			
				|  |  | +                        readLen += bytesAvailableInBuffer;
 | 
	
		
			
				|  |  |                          // advance offset to start writing bytes into caller-provided buffer
 | 
	
		
			
				|  |  |                          offset += bytesAvailableInBuffer;
 | 
	
		
			
				|  |  |                          // update number of bytes left to read
 | 
	
		
			
				|  |  | -                        count -= bytesToWriteToCallerBuffer;
 | 
	
		
			
				|  |  | -                        // record total number of bytes read into caller-provided buffer
 | 
	
		
			
				|  |  | -                        readLen += bytesToWriteToCallerBuffer;
 | 
	
		
			
				|  |  | -                        // update stream position
 | 
	
		
			
				|  |  | -                        _position += bytesToWriteToCallerBuffer;
 | 
	
		
			
				|  |  | +                        count -= bytesAvailableInBuffer;
 | 
	
		
			
				|  |  |                      }
 | 
	
		
			
				|  |  |                  }
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -            // Return the number of bytes that were read to the caller.
 | 
	
		
			
				|  |  | +            // return the number of bytes that were read to the caller.
 | 
	
		
			
				|  |  |              return readLen;
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -418,28 +452,32 @@ namespace Renci.SshNet.Sftp
 | 
	
		
			
				|  |  |                  // Setup the object for reading.
 | 
	
		
			
				|  |  |                  SetupRead();
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +                byte[] readBuffer;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |                  // Read more data into the internal buffer if necessary.
 | 
	
		
			
				|  |  |                  if (_bufferPosition >= _bufferLen)
 | 
	
		
			
				|  |  |                  {
 | 
	
		
			
				|  |  | -                    _bufferPosition = 0;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |                      var data = _session.RequestRead(_handle, (ulong) _position, (uint) _readBufferSize);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -                    _bufferLen = data.Length;
 | 
	
		
			
				|  |  | -                    _serverFilePosition = (ulong) _position;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -                    if (_bufferLen == 0)
 | 
	
		
			
				|  |  | +                    if (data.Length == 0)
 | 
	
		
			
				|  |  |                      {
 | 
	
		
			
				|  |  |                          // We've reached EOF.
 | 
	
		
			
				|  |  |                          return -1;
 | 
	
		
			
				|  |  |                      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -                    Buffer.BlockCopy(data, 0, _readBuffer, 0, _bufferLen);
 | 
	
		
			
				|  |  | +                    readBuffer = GetOrCreateReadBuffer();
 | 
	
		
			
				|  |  | +                    Buffer.BlockCopy(data, 0, readBuffer, 0, data.Length);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                    _bufferPosition = 0;
 | 
	
		
			
				|  |  | +                    _bufferLen = data.Length;
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +                else
 | 
	
		
			
				|  |  | +                {
 | 
	
		
			
				|  |  | +                    readBuffer = GetOrCreateReadBuffer();
 | 
	
		
			
				|  |  |                  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |                  // Extract the next byte from the buffer.
 | 
	
		
			
				|  |  |                  ++_position;
 | 
	
		
			
				|  |  | -                return _readBuffer[_bufferPosition++];
 | 
	
		
			
				|  |  | +                return readBuffer[_bufferPosition++];
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -501,7 +539,6 @@ namespace Renci.SshNet.Sftp
 | 
	
		
			
				|  |  |                          throw new EndOfStreamException("End of stream.");
 | 
	
		
			
				|  |  |                      }
 | 
	
		
			
				|  |  |                      _position = newPosn;
 | 
	
		
			
				|  |  | -                    _serverFilePosition = (ulong)newPosn;
 | 
	
		
			
				|  |  |                  }
 | 
	
		
			
				|  |  |                  else
 | 
	
		
			
				|  |  |                  {
 | 
	
	
		
			
				|  | @@ -510,8 +547,7 @@ namespace Renci.SshNet.Sftp
 | 
	
		
			
				|  |  |                      if (origin == SeekOrigin.Begin)
 | 
	
		
			
				|  |  |                      {
 | 
	
		
			
				|  |  |                          newPosn = _position - _bufferPosition;
 | 
	
		
			
				|  |  | -                        if (offset >= newPosn && offset <
 | 
	
		
			
				|  |  | -                                (newPosn + _bufferLen))
 | 
	
		
			
				|  |  | +                        if (offset >= newPosn && offset < (newPosn + _bufferLen))
 | 
	
		
			
				|  |  |                          {
 | 
	
		
			
				|  |  |                              _bufferPosition = (int)(offset - newPosn);
 | 
	
		
			
				|  |  |                              _position = offset;
 | 
	
	
		
			
				|  | @@ -524,8 +560,7 @@ namespace Renci.SshNet.Sftp
 | 
	
		
			
				|  |  |                          if (newPosn >= (_position - _bufferPosition) &&
 | 
	
		
			
				|  |  |                             newPosn < (_position - _bufferPosition + _bufferLen))
 | 
	
		
			
				|  |  |                          {
 | 
	
		
			
				|  |  | -                            _bufferPosition =
 | 
	
		
			
				|  |  | -                                (int)(newPosn - (_position - _bufferPosition));
 | 
	
		
			
				|  |  | +                            _bufferPosition = (int) (newPosn - (_position - _bufferPosition));
 | 
	
		
			
				|  |  |                              _position = newPosn;
 | 
	
		
			
				|  |  |                              return _position;
 | 
	
		
			
				|  |  |                          }
 | 
	
	
		
			
				|  | @@ -645,14 +680,13 @@ namespace Renci.SshNet.Sftp
 | 
	
		
			
				|  |  |                      {
 | 
	
		
			
				|  |  |                          using (var wait = new AutoResetEvent(false))
 | 
	
		
			
				|  |  |                          {
 | 
	
		
			
				|  |  | -                            _session.RequestWrite(_handle, _serverFilePosition, buffer, offset, tempLen, wait);
 | 
	
		
			
				|  |  | -                            _serverFilePosition += (ulong) tempLen;
 | 
	
		
			
				|  |  | +                            _session.RequestWrite(_handle, (ulong) _position, buffer, offset, tempLen, wait);
 | 
	
		
			
				|  |  |                          }
 | 
	
		
			
				|  |  |                      }
 | 
	
		
			
				|  |  |                      else
 | 
	
		
			
				|  |  |                      {
 | 
	
		
			
				|  |  |                          // No: copy the data to the write buffer first.
 | 
	
		
			
				|  |  | -                        Buffer.BlockCopy(buffer, offset, _writeBuffer, _bufferPosition, tempLen);
 | 
	
		
			
				|  |  | +                        Buffer.BlockCopy(buffer, offset, GetOrCreateWriteBuffer(), _bufferPosition, tempLen);
 | 
	
		
			
				|  |  |                          _bufferPosition += tempLen;
 | 
	
		
			
				|  |  |                      }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -668,8 +702,7 @@ namespace Renci.SshNet.Sftp
 | 
	
		
			
				|  |  |                  {
 | 
	
		
			
				|  |  |                      using (var wait = new AutoResetEvent(false))
 | 
	
		
			
				|  |  |                      {
 | 
	
		
			
				|  |  | -                        _session.RequestWrite(_handle, _serverFilePosition, _writeBuffer, 0, _bufferPosition, wait);
 | 
	
		
			
				|  |  | -                        _serverFilePosition += (ulong) _bufferPosition;
 | 
	
		
			
				|  |  | +                        _session.RequestWrite(_handle, (ulong) (_position - _bufferPosition), GetOrCreateWriteBuffer(), 0, _bufferPosition, wait);
 | 
	
		
			
				|  |  |                      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |                      _bufferPosition = 0;
 | 
	
	
		
			
				|  | @@ -694,20 +727,21 @@ namespace Renci.SshNet.Sftp
 | 
	
		
			
				|  |  |                  // Setup the object for writing.
 | 
	
		
			
				|  |  |                  SetupWrite();
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +                var writeBuffer = GetOrCreateWriteBuffer();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |                  // Flush the current buffer if it is full.
 | 
	
		
			
				|  |  |                  if (_bufferPosition >= _writeBufferSize)
 | 
	
		
			
				|  |  |                  {
 | 
	
		
			
				|  |  |                      using (var wait = new AutoResetEvent(false))
 | 
	
		
			
				|  |  |                      {
 | 
	
		
			
				|  |  | -                        _session.RequestWrite(_handle, _serverFilePosition, _writeBuffer, 0, _bufferPosition, wait);
 | 
	
		
			
				|  |  | -                        _serverFilePosition += (ulong) _bufferPosition;
 | 
	
		
			
				|  |  | +                        _session.RequestWrite(_handle, (ulong) (_position - _bufferPosition), writeBuffer, 0, _bufferPosition, wait);
 | 
	
		
			
				|  |  |                      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |                      _bufferPosition = 0;
 | 
	
		
			
				|  |  |                  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |                  // Write the byte into the buffer and advance the posn.
 | 
	
		
			
				|  |  | -                _writeBuffer[_bufferPosition++] = value;
 | 
	
		
			
				|  |  | +                writeBuffer[_bufferPosition++] = value;
 | 
	
		
			
				|  |  |                  ++_position;
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |          }
 | 
	
	
		
			
				|  | @@ -754,6 +788,20 @@ namespace Renci.SshNet.Sftp
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +        private byte[] GetOrCreateReadBuffer()
 | 
	
		
			
				|  |  | +        {
 | 
	
		
			
				|  |  | +            if (_readBuffer == null)
 | 
	
		
			
				|  |  | +                _readBuffer = new byte[_readBufferSize];
 | 
	
		
			
				|  |  | +            return _readBuffer;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        private byte[] GetOrCreateWriteBuffer()
 | 
	
		
			
				|  |  | +        {
 | 
	
		
			
				|  |  | +            if (_writeBuffer == null)
 | 
	
		
			
				|  |  | +                _writeBuffer = new byte[_writeBufferSize];
 | 
	
		
			
				|  |  | +            return _writeBuffer;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |          /// <summary>
 | 
	
		
			
				|  |  |          /// Flushes the read data from the buffer.
 | 
	
		
			
				|  |  |          /// </summary>
 | 
	
	
		
			
				|  | @@ -779,8 +827,7 @@ namespace Renci.SshNet.Sftp
 | 
	
		
			
				|  |  |              {
 | 
	
		
			
				|  |  |                  using (var wait = new AutoResetEvent(false))
 | 
	
		
			
				|  |  |                  {
 | 
	
		
			
				|  |  | -                    _session.RequestWrite(_handle, _serverFilePosition, _writeBuffer, 0, _bufferPosition, wait);
 | 
	
		
			
				|  |  | -                    _serverFilePosition += (ulong) _bufferPosition;
 | 
	
		
			
				|  |  | +                    _session.RequestWrite(_handle, (ulong) (_position - _bufferPosition), _writeBuffer, 0, _bufferPosition, wait);
 | 
	
		
			
				|  |  |                  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |                  _bufferPosition = 0;
 |