Skip to content

Commit 4b85e78

Browse files
committed
In the SftpFileStream ctor, only obtain file attributes when mode is Append and no longer keep the result as instance field.
Update Seek to only obtain file attributes when SeekOrigin is End. Update SetLength to obtain server file attributes before updating sending an SSH_FXP_FSETSTAT with the new size/length. Fixes issue #154.
1 parent c8373c9 commit 4b85e78

File tree

1 file changed

+25
-25
lines changed

1 file changed

+25
-25
lines changed

src/Renci.SshNet/Sftp/SftpFileStream.cs

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,6 @@ public class SftpFileStream : Stream
3030
private bool _canWrite;
3131
private ulong _serverFilePosition;
3232

33-
private SftpFileAttributes _attributes;
34-
3533
private readonly object _lock = new object();
3634

3735
/// <summary>
@@ -105,12 +103,11 @@ public override long Length
105103
FlushWriteBuffer();
106104
}
107105

108-
// Update file attributes
109-
_attributes = _session.RequestFStat(_handle, true);
110-
111-
if (_attributes != null && _attributes.Size > -1)
106+
// obtain file attributes
107+
var attributes = _session.RequestFStat(_handle, true);
108+
if (attributes != null)
112109
{
113-
return _attributes.Size;
110+
return attributes.Size;
114111
}
115112
throw new IOException("Seek operation failed.");
116113
}
@@ -188,9 +185,9 @@ internal SftpFileStream(ISftpSession session, string path, FileMode mode, FileAc
188185

189186
// Initialize the object state.
190187
_session = session;
191-
_canRead = ((access & FileAccess.Read) != 0);
188+
_canRead = (access & FileAccess.Read) != 0;
192189
_canSeek = true;
193-
_canWrite = ((access & FileAccess.Write) != 0);
190+
_canWrite = (access & FileAccess.Write) != 0;
194191

195192
var flags = Flags.None;
196193

@@ -240,21 +237,20 @@ internal SftpFileStream(ISftpSession session, string path, FileMode mode, FileAc
240237
if (_handle == null)
241238
_handle = _session.RequestOpen(path, flags);
242239

243-
_attributes = _session.RequestFStat(_handle, false);
244-
245240
// instead of using the specified buffer size as is, we use it to calculate a buffer size
246241
// that ensures we always receive or send the max. number of bytes in a single SSH_FXP_READ
247242
// or SSH_FXP_WRITE message
248243

249-
_readBufferSize = (int) session.CalculateOptimalReadLength((uint)bufferSize);
244+
_readBufferSize = (int) session.CalculateOptimalReadLength((uint) bufferSize);
250245
_readBuffer = new byte[_readBufferSize];
251-
_writeBufferSize = (int) session.CalculateOptimalWriteLength((uint)bufferSize, _handle);
246+
_writeBufferSize = (int) session.CalculateOptimalWriteLength((uint) bufferSize, _handle);
252247
_writeBuffer = new byte[_writeBufferSize];
253248

254249
if (mode == FileMode.Append)
255250
{
256-
_position = _attributes.Size;
257-
_serverFilePosition = (ulong) _attributes.Size;
251+
var attributes = _session.RequestFStat(_handle, false);
252+
_position = attributes.Size;
253+
_serverFilePosition = (ulong) attributes.Size;
258254
}
259255
}
260256

@@ -290,13 +286,15 @@ public override void Flush()
290286
}
291287

292288
/// <summary>
293-
/// Reads a sequence of bytes from the current stream and advances the position within the stream by the number of bytes read.
289+
/// Reads a sequence of bytes from the current stream and advances the position within the stream by the
290+
/// number of bytes read.
294291
/// </summary>
295292
/// <param name="buffer">An array of bytes. When this method returns, the buffer contains the specified byte array with the values between <paramref name="offset"/> and (<paramref name="offset"/> + <paramref name="count"/> - 1) replaced by the bytes read from the current source.</param>
296293
/// <param name="offset">The zero-based byte offset in <paramref name="buffer"/> at which to begin storing the data read from the current stream.</param>
297294
/// <param name="count">The maximum number of bytes to be read from the current stream.</param>
298295
/// <returns>
299-
/// The total number of bytes read into the buffer. This can be less than the number of bytes requested if that many bytes are not currently available, or zero (0) if the end of the stream has been reached.
296+
/// The total number of bytes read into the buffer. This can be less than the number of bytes requested
297+
/// if that many bytes are not currently available, or zero (0) if the end of the stream has been reached.
300298
/// </returns>
301299
/// <exception cref="ArgumentException">The sum of <paramref name="offset"/> and <paramref name="count"/> is larger than the buffer length.</exception>
302300
/// <exception cref="ArgumentNullException"><paramref name="buffer"/> is <c>null</c>. </exception>
@@ -413,10 +411,10 @@ public override int ReadByte()
413411
{
414412
_bufferPosition = 0;
415413

416-
var data = _session.RequestRead(_handle, (ulong)_position, (uint)_readBufferSize);
414+
var data = _session.RequestRead(_handle, (ulong) _position, (uint) _readBufferSize);
417415

418416
_bufferLen = data.Length;
419-
_serverFilePosition = (ulong)_position;
417+
_serverFilePosition = (ulong) _position;
420418

421419
if (_bufferLen == 0)
422420
{
@@ -466,8 +464,6 @@ public override long Seek(long offset, SeekOrigin origin)
466464
return _position;
467465
}
468466

469-
_attributes = _session.RequestFStat(_handle, false);
470-
471467
// The behaviour depends upon the read/write mode.
472468
if (_bufferOwnedByWrite)
473469
{
@@ -483,7 +479,8 @@ public override long Seek(long offset, SeekOrigin origin)
483479
newPosn = _position + offset;
484480
break;
485481
case SeekOrigin.End:
486-
newPosn = _attributes.Size - offset;
482+
var attributes = _session.RequestFStat(_handle, false);
483+
newPosn = attributes.Size - offset;
487484
break;
488485
}
489486

@@ -536,7 +533,8 @@ public override long Seek(long offset, SeekOrigin origin)
536533
newPosn = _position + offset;
537534
break;
538535
case SeekOrigin.End:
539-
newPosn = _attributes.Size - offset;
536+
var attributes = _session.RequestFStat(_handle, false);
537+
newPosn = attributes.Size - offset;
540538
break;
541539
}
542540

@@ -573,8 +571,10 @@ public override void SetLength(long value)
573571
throw new NotSupportedException("Seek is not supported.");
574572

575573
SetupWrite();
576-
_attributes.Size = value;
577-
_session.RequestFSetStat(_handle, _attributes);
574+
575+
var attributes = _session.RequestFStat(_handle, false);
576+
attributes.Size = value;
577+
_session.RequestFSetStat(_handle, attributes);
578578
}
579579
}
580580

0 commit comments

Comments
 (0)