-
Notifications
You must be signed in to change notification settings - Fork 4.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
BinaryReader.PeekChar causes excessive reads in underlying Stream if used with BufferedStream #54593
Comments
Tagging subscribers to this area: @dotnet/area-system-io Issue DetailsDescriptionWhen BinaryReader.PeekChar is called multiple times for BufferedStream it will cause read of full buffer with each call. public class CustomStream : Stream {
private readonly FileStream _fileStream;
public CustomStream(FileStream fileStream) {
_fileStream = fileStream;
}
public override int Read(byte[] buffer, int offset, int count) {
Console.WriteLine("Read: count: {0}, pos: {1}, len: {2}, off: {3}", count, Position, Length, offset);
return _fileStream.Read(buffer, offset, count);
}
// other methods are skipped for brevity
}
static void Main(string[] args) {
using var input = new BinaryReader(new BufferedStream(new CustomStream(File.Open("test.rtf", FileMode.Open))));
for (int i = 0; i < 3; i++) {
input.PeekChar();
}
} Running that code will output:
It shows that underlying stream is called to read full buffer (in our case 4096 is a default buffer, but with bigger buffer size it becomes even more prominent) AnalysisFrom what I see, the issue occurs when PeekChar restores it's position: long origPos = _stream.Position;
int ch = Read();
_stream.Position = origPos; and setting Position in BufferedStream resets data in read buffer: if (_writePos > 0)
FlushWrite();
_readPos = 0;
_readLen = 0; // <-- resetting read buffer
_stream!.Seek(value, SeekOrigin.Begin);
|
Seems the point is to try to keep shared buffer data valid as possible even after set_position within some reasonable range. I would like to learn and try it with PR, thanks ! |
Hi, this PR is ready for review now, please review, thanks. Description:
|
Hi @adamsitnik, could you please help review ? |
Description
When BinaryReader.PeekChar is called multiple times for BufferedStream it will cause read of full buffer with each call.
Sample reproduce:
Running that code will output:
It shows that underlying stream is called to read full buffer (in our case 4096 is a default buffer, but with bigger buffer size it becomes even more prominent)
Analysis
From what I see, the issue occurs when PeekChar restores it's position:
and setting Position in BufferedStream resets data in read buffer:
The text was updated successfully, but these errors were encountered: