read method
Reads characters into an array.
This method will block until some input is available, an I/O error occurs, or the end of the stream is reached.
Parameters
cbuf
: Destination bufferoffset
: Offset at which to start storing characters (default: 0)length
: Maximum number of characters to read (default: remaining buffer space)
Returns
The number of characters read, or -1 if the end of the stream has been reached.
Example
final reader = FileReader('text.txt');
try {
final buffer = List<int>.filled(1024, 0);
final charsRead = await reader.read(buffer);
if (charsRead != -1) {
final text = String.fromCharCodes(buffer.sublist(0, charsRead));
print('Read: $text');
}
} finally {
await reader.close();
}
Throws InvalidArgumentException if offset
or length
is negative, or if
offset
+ length
is greater than the length of cbuf
.
Throws IOException if an I/O error occurs.
Throws StreamClosedException if the reader has been closed.
Implementation
@override
Future<int> read(List<int> cbuf, [int offset = 0, int? length]) async {
checkClosed();
length ??= cbuf.length - offset;
if (offset < 0 || length < 0 || offset + length > cbuf.length) {
throw InvalidArgumentException('Invalid offset or length');
}
if (length == 0) {
return 0;
}
int totalRead = 0;
// First, read from buffer if available
if (_position < _count) {
final availableInBuffer = _count - _position;
final toReadFromBuffer = length.clamp(0, availableInBuffer);
cbuf.setRange(offset, offset + toReadFromBuffer, _buffer, _position);
_position += toReadFromBuffer;
totalRead += toReadFromBuffer;
offset += toReadFromBuffer;
length -= toReadFromBuffer;
}
// If we need more data and the request is large, read directly
if (length > 0 && length >= _buffer.length) {
final directRead = await _reader.read(cbuf, offset, length);
if (directRead > 0) {
totalRead += directRead;
} else if (totalRead == 0) {
return -1; // End of stream
}
} else if (length > 0) {
// Fill buffer and read from it
await _fillBuffer();
if (_count > 0) {
final toRead = length.clamp(0, _count);
cbuf.setRange(offset, offset + toRead, _buffer, 0);
_position = toRead;
totalRead += toRead;
} else if (totalRead == 0) {
return -1; // End of stream
}
}
return totalRead;
}