1) RandomAccessFile.seek legt nur die aktuelle Position des Dateizeigers fest, es werden keine Bytes in den Speicher gelesen.
2) Da Ihre Datei UTF-8-codiert ist, handelt es sich um eine Textdatei. Zum Lesen von Textdateien verwenden wir in der Regel BufferedReader, Java 7 hat sogar die convenience-Methode File.newBufferedReader hinzugefügt, um eine Instanz eines BufferedReaders zu erstellen, um Text aus einer Datei zu lesen. Obwohl es ineffizient sein kann, die letzten n Zeilen zu lesen, ist es jedoch einfach zu implementieren.
3) Um effizient zu sein, benötigen wir RandomAccessFile und lesen die Datei rückwärts beginnend vom Ende. Hier ist ein einfaches Beispiel
public static void main(String[] args) throws Exception {
int n = 3;
List<String> lines = new ArrayList<>();
try (RandomAccessFile f = new RandomAccessFile("test", "r")) {
ByteArrayOutputStream bout = new ByteArrayOutputStream();
for (long length = f.length(), p = length - 1; p > 0 && lines.size() < n; p--) {
f.seek(p);
int b = f.read();
if (b == 10) {
if (p < length - 1) {
lines.add(0, getLine(bout));
bout.reset();
}
} else if (b != 13) {
bout.write(b);
}
}
}
System.out.println(lines);
}
static String getLine(ByteArrayOutputStream bout) {
byte[] a = bout.toByteArray();
// reverse bytes
for (int i = 0, j = a.length - 1; j > i; i++, j--) {
byte tmp = a[j];
a[j] = a[i];
a[i] = tmp;
}
return new String(a);
}
Es liest die Datei Byte für Byte Ausgang vom Schwanz zum ByteArrayOutputStream, wenn LF erreicht wird, die Bytes umkehrt und erstellt eine Zeile.
Zwei Dinge müssen verbessert werden: 1) Pufferung 2) EOL Erkennung
Und nein, 'seek()' liest nichts * in den Speicher, geschweige denn die ganze Datei. Sie haben die volle Kontrolle. – NPE
Ich lese diese Frage durch, aber ich würde gerne verstehen, wenn die Datei wenn UTF-8 codiert, wird dann die Verwendung von RandomAccessFile abgeraten? –
Nicht einverstanden mit Duplikat. Dies konzentriert sich mehr auf RandomAccessFile, während der andere sich mehr auf die Anwendung bezieht und RAF nicht einmal erwähnt. –