Я использую какую-то реализацию tail -f, чтобы отслеживать изменения в файле (почти как это ). Для этого я использую RandomAccessFile, периодически проверяю, не увеличилась ли длина файла и если да, то ищу и считываю новые строки (все происходит в отдельном потоке FileTailer).
Теперь все работает, как и ожидалось, в Windows, но я протестировал свою программу в Linux, и она не работает должным образом. Вот метод run() класса FileTailer. В частности, в linux происходит сбой в той части, где вызывается file.seek(filePointer), а затем вызывается file.readLine(), из которых последний неожиданно возвращает NULL (хотя filePointer правильно увеличивается, если я добавляю содержимое в файл, получая хвост в время выполнения).
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();
}
}
Как я уже сказал, в Windows все работает как надо, но в Linux строковая переменная «line» имеет значение NULL после того, как она должна была быть заполнена новой добавленной строкой, поэтому fireNewLine вызывается на NULL, и все идет к чертям.
Кто-нибудь знает, почему это происходит в системах Linux?
seek()
, но я не знаю, почему вы вообще звонитеseek()
. Вам не нужно. Вы всегда должны располагаться в конце файла. Ничто не изменит вашу позицию в файле, кроме ваших собственныхreadLine()
вызовов. - person user207421   schedule 22.06.2017RandomAccessFile
вообще не нужно. ИспользуйтеBufferedReader
и просто спите, покаreadLine()
возвращает значение null. - person user207421   schedule 22.06.2017