diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/StreamReader.cs b/src/libraries/System.Private.CoreLib/src/System/IO/StreamReader.cs index cd3bc29187abdb..e06a2512264c8d 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/StreamReader.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/StreamReader.cs @@ -25,7 +25,6 @@ public class StreamReader : TextReader // saves construction time. This does break adaptive buffering, // but this is slightly faster. private const int DefaultBufferSize = 1024; // Byte buffer size - private const int DefaultFileStreamBufferSize = 4096; private const int MinBufferSize = 128; private readonly Stream _stream; @@ -123,7 +122,7 @@ public StreamReader(Stream stream, Encoding? encoding, bool detectEncodingFromBy // Creates a new StreamReader for the given stream. The // character encoding is set by encoding and the buffer size, - // in number of 16-bit characters, is set by bufferSize. + // in bytes, is set by bufferSize. // // Note that detectEncodingFromByteOrderMarks is a very // loose attempt at detecting the encoding by looking at the first @@ -227,9 +226,13 @@ private static FileStream ValidateArgsAndOpenPath(string path, FileStreamOptions private static FileStream ValidateArgsAndOpenPath(string path, int bufferSize) { ArgumentException.ThrowIfNullOrEmpty(path); - ArgumentOutOfRangeException.ThrowIfNegativeOrZero(bufferSize); - return new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, DefaultFileStreamBufferSize); + if (bufferSize != -1) + { + ArgumentOutOfRangeException.ThrowIfNegativeOrZero(bufferSize); + } + + return new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, FileStream.DefaultBufferSize); } public override void Close() diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/StreamWriter.cs b/src/libraries/System.Private.CoreLib/src/System/IO/StreamWriter.cs index 229509254e1d99..4f370df7937b0f 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/StreamWriter.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/StreamWriter.cs @@ -24,7 +24,6 @@ public class StreamWriter : TextWriter // which means we take advantage of adaptive buffering code. // The performance using UnicodeEncoding is acceptable. private const int DefaultBufferSize = 1024; // char[] - private const int DefaultFileStreamBufferSize = 4096; private const int MinBufferSize = 128; // Bit bucket - Null has no backing store. Non closable. @@ -156,7 +155,7 @@ public StreamWriter(string path, FileStreamOptions options) } public StreamWriter(string path, Encoding? encoding, FileStreamOptions options) - : this(ValidateArgsAndOpenPath(path, options), encoding, DefaultFileStreamBufferSize) + : this(ValidateArgsAndOpenPath(path, options), encoding, DefaultBufferSize) { } @@ -184,9 +183,13 @@ private static FileStream ValidateArgsAndOpenPath(string path, FileStreamOptions private static FileStream ValidateArgsAndOpenPath(string path, bool append, int bufferSize) { ArgumentException.ThrowIfNullOrEmpty(path); - ArgumentOutOfRangeException.ThrowIfNegativeOrZero(bufferSize); - return new FileStream(path, append ? FileMode.Append : FileMode.Create, FileAccess.Write, FileShare.Read, DefaultFileStreamBufferSize); + if (bufferSize != -1) + { + ArgumentOutOfRangeException.ThrowIfNegativeOrZero(bufferSize); + } + + return new FileStream(path, append ? FileMode.Append : FileMode.Create, FileAccess.Write, FileShare.Read, FileStream.DefaultBufferSize); } public override void Close() diff --git a/src/libraries/System.Runtime/tests/System.IO.Tests/StreamReader/StreamReader.CtorTests.cs b/src/libraries/System.Runtime/tests/System.IO.Tests/StreamReader/StreamReader.CtorTests.cs index c7bf35f44eced1..3522d8b94be31c 100644 --- a/src/libraries/System.Runtime/tests/System.IO.Tests/StreamReader/StreamReader.CtorTests.cs +++ b/src/libraries/System.Runtime/tests/System.IO.Tests/StreamReader/StreamReader.CtorTests.cs @@ -68,6 +68,34 @@ byte[] GetEncodedDataWithPreamble(byte[] data, Encoding encoding) => encoding.GetPreamble().Concat(data).ToArray(); } + [Fact] + public static void NegativeBufferSize_ThrowsArgumentOutOfRangeException() + { + var ms2 = new MemoryStream(); + + AssertExtensions.Throws("bufferSize", () => new StreamReader(ms2, bufferSize: -2)); + AssertExtensions.Throws("bufferSize", () => new StreamReader(ms2, bufferSize: 0)); + + ms2.Dispose(); + } + + [Fact] + public static void NegativeOneBufferSize_ShouldNotThrowException() + { + var ms2 = new MemoryStream(); + try + { + using (var sr = new StreamReader(ms2, bufferSize: -1)) + { + Assert.NotNull(sr); + } + } + finally + { + ms2.Dispose(); + } + } + [Theory] [MemberData(nameof(EncodingsWithEncodedDataWithPreamble))] public static void CreationFromMemoryStreamWithEncodingTrueDetectsCorrectEncodingWhenPreambleAvailable(Encoding expectedEncoding, byte[] encodedData, string expectedOutput) diff --git a/src/libraries/System.Runtime/tests/System.IO.Tests/StreamReader/StreamReader.StringCtorTests.cs b/src/libraries/System.Runtime/tests/System.IO.Tests/StreamReader/StreamReader.StringCtorTests.cs index 4cab5d2134290e..aea7a4c269cd5f 100644 --- a/src/libraries/System.Runtime/tests/System.IO.Tests/StreamReader/StreamReader.StringCtorTests.cs +++ b/src/libraries/System.Runtime/tests/System.IO.Tests/StreamReader/StreamReader.StringCtorTests.cs @@ -50,10 +50,27 @@ public static void NullEncodingParamInCtor_ShouldNotThrowException() [Fact] public static void NegativeBufferSize_ThrowsArgumentOutOfRangeException() { - AssertExtensions.Throws("bufferSize", () => new StreamReader("path", Encoding.UTF8, true, -1)); + AssertExtensions.Throws("bufferSize", () => new StreamReader("path", Encoding.UTF8, true, -2)); AssertExtensions.Throws("bufferSize", () => new StreamReader("path", Encoding.UTF8, true, 0)); } + [Fact] + public static void NegativeOneBufferSize_ShouldNotThrowException() + { + string testfile = Path.GetTempFileName(); + try + { + using (var sr = new StreamReader(testfile, Encoding.UTF8, true, -1)) + { + Assert.NotNull(sr); + } + } + finally + { + File.Delete(testfile); + } + } + [Fact] public static void LackOfReadAccess_ThrowsArgumentException() { diff --git a/src/libraries/System.Runtime/tests/System.IO.Tests/StreamWriter/StreamWriter.CtorTests.cs b/src/libraries/System.Runtime/tests/System.IO.Tests/StreamWriter/StreamWriter.CtorTests.cs index bf0075139e699d..936e811bbcff5a 100644 --- a/src/libraries/System.Runtime/tests/System.IO.Tests/StreamWriter/StreamWriter.CtorTests.cs +++ b/src/libraries/System.Runtime/tests/System.IO.Tests/StreamWriter/StreamWriter.CtorTests.cs @@ -70,5 +70,33 @@ private static void TestEncoding(System.Text.Encoding? encoding, string testStri str2 = sr2.ReadToEnd(); Assert.Equal(testString, str2); } + + [Fact] + public static void NegativeBufferSize_ThrowsArgumentOutOfRangeException() + { + var ms2 = new MemoryStream(); + + AssertExtensions.Throws("bufferSize", () => new StreamWriter(ms2, bufferSize: -2)); + AssertExtensions.Throws("bufferSize", () => new StreamWriter(ms2, bufferSize: 0)); + + ms2.Dispose(); + } + + [Fact] + public static void NegativeOneBufferSize_ShouldNotThrowException() + { + var ms2 = new MemoryStream(); + try + { + using (var sw = new StreamWriter(ms2, bufferSize: -1)) + { + Assert.NotNull(sw); + } + } + finally + { + ms2.Dispose(); + } + } } } diff --git a/src/libraries/System.Runtime/tests/System.IO.Tests/StreamWriter/StreamWriter.StringCtorTests.cs b/src/libraries/System.Runtime/tests/System.IO.Tests/StreamWriter/StreamWriter.StringCtorTests.cs index ec94e8cb606372..c1a1fff544038c 100644 --- a/src/libraries/System.Runtime/tests/System.IO.Tests/StreamWriter/StreamWriter.StringCtorTests.cs +++ b/src/libraries/System.Runtime/tests/System.IO.Tests/StreamWriter/StreamWriter.StringCtorTests.cs @@ -37,10 +37,27 @@ public static void EmptyPath_ThrowsArgumentException() [Fact] public static void NegativeBufferSize_ThrowsArgumentOutOfRangeException() { - AssertExtensions.Throws("bufferSize", () => new StreamWriter("path", false, Encoding.UTF8, -1)); + AssertExtensions.Throws("bufferSize", () => new StreamWriter("path", false, Encoding.UTF8, -2)); AssertExtensions.Throws("bufferSize", () => new StreamWriter("path", true, Encoding.UTF8, 0)); } + [Fact] + public static void NegativeOneBufferSize_ShouldNotThrowException() + { + string testfile = Path.GetTempFileName(); + try + { + using (StreamWriter sw = new StreamWriter(testfile, false, Encoding.UTF8, -1)) + { + Assert.NotNull(sw); + } + } + finally + { + File.Delete(testfile); + } + } + [Fact] public static void LackOfWriteAccess_ThrowsArgumentException() {