Skip to content

Commit 48205c7

Browse files
committed
Improve SetLength compatibility with FileStream:
* Flush any buffers before epand or shrink the stream. * If the specified value is less than the current length of the stream, the current position is moved to the last byte of the stream.
1 parent f38c7ce commit 48205c7

File tree

1 file changed

+28
-3
lines changed

1 file changed

+28
-3
lines changed

src/Renci.SshNet/Sftp/SftpFileStream.cs

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -602,13 +602,26 @@ public override long Seek(long offset, SeekOrigin origin)
602602
}
603603

604604
/// <summary>
605-
/// When overridden in a derived class, sets the length of the current stream.
605+
/// Sets the length of the current stream.
606606
/// </summary>
607607
/// <param name="value">The desired length of the current stream in bytes.</param>
608608
/// <exception cref="IOException">An I/O error occurs.</exception>
609-
/// <exception cref="NotSupportedException">The stream does not support both writing and seeking, such as if the stream is constructed from a pipe or console output.</exception>
609+
/// <exception cref="NotSupportedException">The stream does not support both writing and seeking.</exception>
610610
/// <exception cref="ObjectDisposedException">Methods were called after the stream was closed.</exception>
611611
/// <exception cref="ArgumentOutOfRangeException"><paramref name="value"/> must be greater than zero.</exception>
612+
/// <remarks>
613+
/// <para>
614+
/// Buffers are first flushed.
615+
/// </para>
616+
/// <para>
617+
/// If the specified value is less than the current length of the stream, the stream is truncated and - if the
618+
/// current position is greater than the new length - the current position is moved to the last byte of the stream.
619+
/// </para>
620+
/// <para>
621+
/// If the given value is greater than the current length of the stream, the stream is expanded and the current
622+
/// position remains the same.
623+
/// </para>
624+
/// </remarks>
612625
public override void SetLength(long value)
613626
{
614627
if (value < 0)
@@ -622,11 +635,23 @@ public override void SetLength(long value)
622635
if (!CanSeek)
623636
throw new NotSupportedException("Seek is not supported.");
624637

625-
SetupWrite();
638+
if (_bufferOwnedByWrite)
639+
{
640+
FlushWriteBuffer();
641+
}
642+
else
643+
{
644+
SetupWrite();
645+
}
626646

627647
var attributes = _session.RequestFStat(_handle, false);
628648
attributes.Size = value;
629649
_session.RequestFSetStat(_handle, attributes);
650+
651+
if (_position > value)
652+
{
653+
_position = value;
654+
}
630655
}
631656
}
632657

0 commit comments

Comments
 (0)