Ich benutze eine Art von Tail-f-Implementierung, um eine Datei für Änderungen (ähnlich wie this) Schwanz. Dazu benutze ich eine RandomAccessFile, überprüfe regelmäßig, ob die Dateilänge zugenommen hat und wenn ja, suche und lese die neuen Zeilen (alles passiert in einem separaten Thread des FileTailers).RandomAccessFile.seek() funktioniert nicht unter Linux
Jetzt funktioniert alles wie erwartet unter Windows, aber ich habe mein Programm unter Linux getestet und es funktioniert nicht wie erwartet. Hier ist die run() - Methode der FileTailer-Klasse. Insbesondere, wo es auf Linux fehlschlägt, ist der Teil, wo file.seek (filePointer) aufgerufen wird und dann file.readLine(), von denen letzteres überraschend NULL zurückgibt (obwohl der filePointer wird richtig inkrementiert, wenn ich Inhalt an die Datei angehängt an anhängen Laufzeit).
public void run() {
// The file pointer keeps track of where we are in the file
long filePointer = 0;
// Determine start point
if(startAtBeginning){
filePointer = 0;
}
else {
filePointer = logfile.length();
}
try {
// Start tailing
tailing = true;
RandomAccessFile file = new RandomAccessFile(logfile, "r");
while(tailing) {
// Compare the length of the file to the file pointer
long fileLength = logfile.length();
System.out.println("filePointer = " + filePointer + " | fileLength = " + fileLength);
if(fileLength < filePointer) {
// Log file must have been rotated or deleted;
// reopen the file and reset the file pointer
file = new RandomAccessFile(logfile, "r");
filePointer = 0;
}
if(fileLength > filePointer) {
// There is data to read
file.seek(filePointer);
String line = file.readLine();
System.out.println("new line = " + line);
while(line != null){
if(!line.isEmpty())
try {
fireNewFileLine(line);
} catch (ParseException e) {
e.printStackTrace();
}
line = file.readLine();
}
filePointer = file.getFilePointer();
}
// Sleep for the specified interval
sleep(sampleInterval);
}
// Close the file that we are tailing
file.close();
}
catch(InterruptedException | IOException e){
e.printStackTrace();
}
}
Wie ich schon sagte, alles funktioniert, wie es unter Windows soll, aber unter Linux der String-Variable „Linie“ ist NULL, nachdem es mit der neu angehängten Zeile gefüllt worden sein, so fireNewLine auf NULL aufgerufen wird und alles geht zu scheiße.
Hat jemand eine Idee, warum dies auf Linux-Systemen passiert?
Es gibt keinen Beweis, dass hier 'seek()' ist das Problem, aber ich weiß nicht, warum Sie anrufen 'seek()' überhaupt. Das musst du nicht. Sie sollten immer am Ende der Datei positioniert werden. Nichts wird Ihre Position in der Datei ändern, außer Ihren eigenen 'readLine()' Aufrufen. – EJP
Und in der Tat brauchen Sie 'RandomAccessFile' nicht in allen. Verwenden Sie einen 'BufferedReader' und schlafen Sie nur, während 'readLine()' null zurückgibt. – EJP