java获取文件最后一行的几种方式

当我们在读取文件的时候,通常都是从前向后读取,那如果要读取文件的最后一行内容,要如何操作呢?

顺序遍历读取,直到文件最后一行
public static String readLastLineV0(File file) {
  String lastLine = "";
  try (BufferedReader bufferedReader = new BufferedReader(new FileReader(file))) {
    String currentLine = "";
    while ((currentLine = bufferedReader.readLine()) != null) {
      lastLine = currentLine;
    }
  } catch (Exception e) {
    log.error("file read error, msg:{}", e.getMessage(), e);
  }

  return lastLine;
}

该方式很简单,从前向后读取即可,直到最后一行。

利用RandomAccessFile指定位置,从后向前读取
public static String readLastLineV1(File file) {
  // 存储结果
  StringBuilder builder = new StringBuilder();
  try (RandomAccessFile randomAccessFile = new RandomAccessFile(file, "r")) {
    // 指针位置开始为0,所以最大长度为 length-1
    long fileLastPointer = randomAccessFile.length() - 1;
    // 从后向前读取文件
    for (long filePointer = fileLastPointer; filePointer != -1; filePointer--) {
      // 移动指针指向
      randomAccessFile.seek(filePointer);
      int readByte = randomAccessFile.readByte();
      if (0xA == readByte) {
        //  LF='\n'=0x0A 换行
        if (filePointer == fileLastPointer) {
          // 如果是最后的换行,过滤掉
          continue;
        }
        break;
      }
      if (0xD == readByte) {
        //  CR ='\r'=0x0D 回车
        if (filePointer == fileLastPointer - 1) {
          // 如果是倒数的回车也过滤掉
          continue;
        }
        break;
      }
      builder.append((char) readByte);
    }
  } catch (Exception e) {
    log.error("file read error, msg:{}", e.getMessage(), e);
  }
  return builder.reverse().toString();
}

该方式主要是利用RandomAccessFile可以seek到指定位置读取的方式。从文件的最后向前读取,当遇到0xA(换行)或者0xD(回车)时,利用StringBuilder缓存一下读取到的数据,最后将数据reverse即是最后一行数据。

利用commons-io中的ReversedLinesFileReader

maven导入依赖

<dependency>
  <groupId>commons-iogroupId>
  <artifactId>commons-ioartifactId>
  <version>2.7version>
dependency>
public static String readLastLineV2(File file) {
  String lastLine = "";
  try (ReversedLinesFileReader reversedLinesReader = new ReversedLinesFileReader(file, Charset.defaultCharset())) {
    lastLine = reversedLinesReader.readLine();
  } catch (Exception e) {
    log.error("file read error, msg:{}", e.getMessage(), e);
  }
  return lastLine;
}

该方式可以直接读取到最后一行数据。有兴趣的同学可以自行看一下源码,非常少。它的实现是思路是先将文件拆成多个FilePart。读取位置定位是基于SeekableByteChannel的position方法。而FilePart的readLine实现中,可以一次读取多个bytes。

总结

以上三种读取文件最后一行的方法中,推荐使用commons-io中的ReversedLinesFileReader,使用方式也比较简单。

你可能感兴趣的:(java,java)