diff --git a/src/libraries/System.IO.FileSystem/tests/FileStream/Seek.cs b/src/libraries/System.IO.FileSystem/tests/FileStream/Seek.cs index 963a1fddff57d4..d934fa2b7730de 100644 --- a/src/libraries/System.IO.FileSystem/tests/FileStream/Seek.cs +++ b/src/libraries/System.IO.FileSystem/tests/FileStream/Seek.cs @@ -7,8 +7,10 @@ namespace System.IO.Tests { public class FileStream_Seek : FileSystemTest { - [Fact] - public void SeekAppendModifyThrows() + [Theory] + [InlineData(0)] + [InlineData(10)] + public void SeekAppendModifyThrows(int bufferSize) { string fileName = GetTestFilePath(); using (FileStream fs = new FileStream(fileName, FileMode.Create)) @@ -16,7 +18,7 @@ public void SeekAppendModifyThrows() fs.Write(TestBuffer, 0, TestBuffer.Length); } - using (FileStream fs = new FileStream(fileName, FileMode.Append)) + using (FileStream fs = new FileStream(fileName, FileMode.Append, FileAccess.Write, FileShare.Read, bufferSize)) { long length = fs.Length; Assert.Throws(() => fs.Seek(length - 1, SeekOrigin.Begin)); @@ -33,6 +35,9 @@ public void SeekAppendModifyThrows() Assert.Throws(() => fs.Seek(-length, SeekOrigin.End)); Assert.Equal(length, fs.Position); + Assert.Throws(() => fs.Position = length - 1); + Assert.Equal(length, fs.Position); + fs.Write(TestBuffer); Assert.Equal(length, fs.Seek(length, SeekOrigin.Begin)); } diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/FileStream.cs b/src/libraries/System.Private.CoreLib/src/System/IO/FileStream.cs index 83b406d4eec90d..9fa6984f59e4b9 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/FileStream.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/FileStream.cs @@ -487,8 +487,17 @@ public override long Position { ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.value, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum); } + else if (!CanSeek) + { + if(_strategy.IsClosed) + { + ThrowHelper.ThrowObjectDisposedException_FileClosed(); + } + + ThrowHelper.ThrowNotSupportedException_UnseekableStream(); + } - _strategy.Seek(value, SeekOrigin.Begin); + _strategy.Position = value; } } @@ -575,7 +584,24 @@ public override void EndWrite(IAsyncResult asyncResult) public override bool CanSeek => _strategy.CanSeek; - public override long Seek(long offset, SeekOrigin origin) => _strategy.Seek(offset, origin); + public override long Seek(long offset, SeekOrigin origin) + { + if (origin < SeekOrigin.Begin || origin > SeekOrigin.End) + { + throw new ArgumentException(SR.Argument_InvalidSeekOrigin, nameof(origin)); + } + else if (!CanSeek) + { + if (_strategy.IsClosed) + { + ThrowHelper.ThrowObjectDisposedException_FileClosed(); + } + + ThrowHelper.ThrowNotSupportedException_UnseekableStream(); + } + + return _strategy.Seek(offset, origin); + } internal Task BaseFlushAsync(CancellationToken cancellationToken) => base.FlushAsync(cancellationToken); diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/Strategies/BufferedFileStreamStrategy.cs b/src/libraries/System.Private.CoreLib/src/System/IO/Strategies/BufferedFileStreamStrategy.cs index 9e9700339014d8..c2227e72469b24 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/Strategies/BufferedFileStreamStrategy.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/Strategies/BufferedFileStreamStrategy.cs @@ -65,15 +65,7 @@ public override long Position } set { - if (_writePos > 0) - { - FlushWrite(); - } - - _readPos = 0; - _readLen = 0; - - _strategy.Position = value; + Seek(value, SeekOrigin.Begin); } } @@ -904,9 +896,6 @@ public override void CopyTo(Stream destination, int bufferSize) public override long Seek(long offset, SeekOrigin origin) { - EnsureNotClosed(); - EnsureCanSeek(); - // If we have bytes in the write buffer, flush them out, seek and be done. if (_writePos > 0) { diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/Strategies/OSFileStreamStrategy.cs b/src/libraries/System.Private.CoreLib/src/System/IO/Strategies/OSFileStreamStrategy.cs index 43f7152167cd3d..b9f6c9eeccbea5 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/Strategies/OSFileStreamStrategy.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/Strategies/OSFileStreamStrategy.cs @@ -85,7 +85,7 @@ internal void OnIncompleteOperation(int expectedBytesTransferred, int actualByte public sealed override long Position { get => _filePosition; - set => _filePosition = value; + set => Seek(value, SeekOrigin.Begin); } internal sealed override string Name => _fileHandle.Path ?? SR.IO_UnknownFileName; @@ -144,11 +144,6 @@ internal sealed override void Flush(bool flushToDisk) public sealed override long Seek(long offset, SeekOrigin origin) { - if (origin < SeekOrigin.Begin || origin > SeekOrigin.End) - throw new ArgumentException(SR.Argument_InvalidSeekOrigin, nameof(origin)); - if (_fileHandle.IsClosed) ThrowHelper.ThrowObjectDisposedException_FileClosed(); - if (!CanSeek) ThrowHelper.ThrowNotSupportedException_UnseekableStream(); - long oldPos = _filePosition; long pos = origin switch {