Ich würde eine Abbildung zwischen Zeilenpositionen und Blöcken (gleicher Größe) innerhalb der Datei machen.
Dafür würde ich für mir jeden Block, an den ich ausgelesen habe, merken, welche die erste Zeilennummer im Block ist.
Als Blockgröße würde ich 4kB vorschlagen, wenn du eh mit Memory Mapped Files arbeitest.
Der Index wäre dann aber auch relativ groß (ca. 20MB-40MB bei einer 20GB großen Datei).
Bei größeren Blöcken (zB. 4MB) wäre er entsprechend kleiner (20kB-40kB).
Damit würde Springen zu bestimmten Zeilen in der Datei relativ schnell