有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java随机访问文件。seek()在Linux上不工作

我正在使用某种tail-f实现来跟踪文件的更改(非常类似于this)。为此,我使用一个RandomAccessFile,定期检查文件长度是否增加,如果增加,则查找并读取新行(在FileTailer的单独线程中发生的所有事情)

现在,Windows上的一切都正常工作,但我在Linux上测试了我的程序,但它没有按预期工作。下面是FileTailer类的run()-方法。具体地说,在linux上失败的地方是文件所在的部分。调用seek(filePointer),然后调用file。readLine(),后者意外地返回NULL(尽管如果我在运行时将内容追加到文件中,文件指针会正确递增)

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系统上会发生这种情况吗


共 (1) 个答案

  1. # 1 楼答案

    你不需要所有这些,或者RandomAccessFile。你总是在文件的末尾。您所需要的就是:

    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();
        }
    }
    

    可能有一些重新打开文件的规定

    E&;OE