Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

//
// Note that detectEncodingFromByteOrderMarks is a very
// loose attempt at detecting the encoding by looking at the first
Expand Down Expand Up @@ -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()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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)
{
}

Expand Down Expand Up @@ -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()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<ArgumentOutOfRangeException>("bufferSize", () => new StreamReader(ms2, bufferSize: -2));
AssertExtensions.Throws<ArgumentOutOfRangeException>("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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,27 @@ public static void NullEncodingParamInCtor_ShouldNotThrowException()
[Fact]
public static void NegativeBufferSize_ThrowsArgumentOutOfRangeException()
{
AssertExtensions.Throws<ArgumentOutOfRangeException>("bufferSize", () => new StreamReader("path", Encoding.UTF8, true, -1));
AssertExtensions.Throws<ArgumentOutOfRangeException>("bufferSize", () => new StreamReader("path", Encoding.UTF8, true, -2));
AssertExtensions.Throws<ArgumentOutOfRangeException>("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()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<ArgumentOutOfRangeException>("bufferSize", () => new StreamWriter(ms2, bufferSize: -2));
AssertExtensions.Throws<ArgumentOutOfRangeException>("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();
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,27 @@ public static void EmptyPath_ThrowsArgumentException()
[Fact]
public static void NegativeBufferSize_ThrowsArgumentOutOfRangeException()
{
AssertExtensions.Throws<ArgumentOutOfRangeException>("bufferSize", () => new StreamWriter("path", false, Encoding.UTF8, -1));
AssertExtensions.Throws<ArgumentOutOfRangeException>("bufferSize", () => new StreamWriter("path", false, Encoding.UTF8, -2));
AssertExtensions.Throws<ArgumentOutOfRangeException>("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()
{
Expand Down
Loading