Skip to content

StreamWriter/StreamReader buffer size inconsistencies #118748

@mriehm

Description

@mriehm

Description

Default buffer size value
The StreamWriter constructor overload that takes FileStreamOptions uses a buffer size of DefaultFileStreamBufferSize (4096) for the StreamWriter char buffer, but all other StreamWriter overloads without a caller-specified buffer size use DefaultBufferSize (1024). This is clearly a mistake and that DefaultFileStreamBufferSize was only intended to be used as the default buffer size of the FileStream byte buffer, not the StreamWriter char buffer.
Compare with the StreamReader constructor overload that takes FileStreamOptions, which correctly uses a buffer size of DefaultBufferSize (1024).

It's not clear why the DefaultFileStreamBufferSize constant is even defined in StreamReader or StreamWriter. The default buffer size of FileStream itself is also 4096, so StreamWriter and StreamReader could just use the FileStream constructor overload that doesn't require a bufferSize and get the same result. Neither StreamWriter nor StreamReader reference DefaultFileStreamBufferSize when using FileStreamOptions anyway.

Also, the StreamWriter constructor docs are inaccurate, since the bufferSize description is "The buffer size, in bytes.", but it actually indicates the size of a char[], not a byte[].
The StreamReader constructor docs are better, though inconsistent. One of the StreamReader overloads gives the complete correct description of "The minimum buffer size, in number of 16-bit characters.", but the other overloads just say "The minimum buffer size." without specifying the unit.

ArgumentOutOfRangeException conditions
The StreamWriter and StreamReader constructors that take a Stream allow bufferSize to be explicitly passed as -1 to use the default buffer size, but the constructors that take a file path throw an ArgumentOutOfRangeException if -1 is passed as the buffer size. I can't think of a reason for this inconsistency.

The StreamWriter docs claim every constructor throws ArgumentOutOfRangeException when "bufferSize is negative.", which is incorrect because -1 is accepted for Stream-accepting overloads. Also, it fails to mention that ArgumentOutOfRangeException is also thrown when bufferSize is 0.
The StreamReader docs claim ArgumentOutOfRangeException is thrown when "bufferSize is less than or equal to zero.", which at least mentions that 0 throws, but it still doesn't mention that -1 doesn't throw for the Stream-accepting overloads. Also, the docs for one of the StreamReader constructors doesn't mention ArgumentOutOfRangeException at all.

Reproduction Steps

Default buffer size value

new StreamWriter(@"C:\temp\test.txt", new FileStreamOptions())

ArgumentOutOfRangeException conditions

new StreamWriter(@"C:\temp\test.txt", append: false, Encoding.UTF8, -1)

Expected behavior

Default buffer size value
Uses buffer size consistent with all other StreamWriter constructors (1024 chars)

ArgumentOutOfRangeException conditions
Uses default buffer size

Actual behavior

Default buffer size value
Uses buffer size inconsistent with all other StreamWriter constructors (4096 chars)

ArgumentOutOfRangeException conditions
Throws ArgumentOutOfRangeException

Regression?

No response

Known Workarounds

No response

Configuration

No response

Other information

No response

Metadata

Metadata

Assignees

Labels

area-System.IOgood first issueIssue should be easy to implement, good for first-time contributorshelp wanted[up-for-grabs] Good issue for external contributors

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions