2017-06-22 7 views
0

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?

+0

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

+0

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

Antwort

0

Sie brauchen dies nicht oder RandomAccessFile. Sie befinden sich immer am Ende der Datei. Alles, was Sie brauchen, ist dies:

public void run() { 

    try { 
     // Start tailing 
     tailing = true; 
     BufferedReader reader = new BufferedReader(new FileReader(logfile)); 
     String line; 
     while (tailing) { 
      while ((line = reader.readLine() != null) { 
       System.out.println("new line = " + line); 
       if(!line.isEmpty()) { 
        try { 
         fireNewFileLine(line); 
        } catch (ParseException e) { 
         e.printStackTrace(); 
        } 
       } 
      } 
      // Sleep for the specified interval 
      sleep(sampleInterval); 
     } 
     // Close the file that we are tailing 
     reader.close(); 
    } catch(InterruptedException | IOException e) { 
     e.printStackTrace(); 
    } 
} 

mit vielleicht einige Vorkehrungen für das erneute Öffnen der Datei.

E & OE

Verwandte Themen