readLinesReverse function
Async generator that yields lines from a file in reverse order. Reads the file backwards in chunks to avoid loading the entire file into memory.
Implementation
Stream<String> readLinesReverse(String path) async* {
const chunkSize = 1024 * 4;
final raf = await File(path).open(mode: FileMode.read);
try {
final size = await raf.length();
int position = size;
List<int> remainder = [];
final buffer = Uint8List(chunkSize);
while (position > 0) {
final currentChunkSize = min(chunkSize, position);
position -= currentChunkSize;
await raf.setPosition(position);
final readCount = await raf.readInto(buffer, 0, currentChunkSize);
final combined = <int>[...buffer.sublist(0, readCount), ...remainder];
final newlineChar = '\n'.codeUnitAt(0);
final firstNewline = combined.indexOf(newlineChar);
if (firstNewline == -1) {
remainder = combined;
continue;
}
remainder = combined.sublist(0, firstNewline);
final text = String.fromCharCodes(combined, firstNewline + 1);
final lines = text.split('\n');
for (int i = lines.length - 1; i >= 0; i--) {
final line = lines[i];
if (line.isNotEmpty) {
yield line;
}
}
}
if (remainder.isNotEmpty) {
yield String.fromCharCodes(remainder);
}
} finally {
await raf.close();
}
}