项目里需要读取最新的日志,可是最新的日志都在文件的最后几行,所以有了这个需求。
   
   百度之后先研究了别人的代码,感觉一是逻辑不太好理解且注释比较少,二是代码偏向于演示,会有bug,没有办法拿来就用。所以自己写了这个方法,希望可以给需要的同学带来帮助。
   
   
    
     这个方法实现的功能和Linux系统的tail命令是相同的。
    
   
  
  
   对这个方法我前前后后投入了很大精力,每改变一次实现方式,前面的工作都仿佛白做了一样。从读取功能基本实现,到解决读取空行和文档行数不足导致的bug。再到费尽心机的简化代码,到最后一次实现方式的改变直接解决之前所有问题。到考虑性能把缓存工具的更换和代码执行逻辑的优化。
   
   这个过程让我意识到:再简单的需求,用上复杂的实现就算把人累死也得不到好的结果。作为一名程序员,拿到需求我们往往急于写代码,当看到杂乱的实现代码,我们又抓耳挠腮无从下手去改进。每当这个时候,我们一定要回头去看看我们的需求,想想有没有其他更简洁的实现方法,而不要困死在已有的代码里。
  
  
   感谢 @万物皆字节 同学的建议。
  
  
   如果这篇博客帮助到了你,你可给它点个赞,这将是对我莫大的鼓励,谢谢!
  
  * 读取文件最后几行 <br>
     * 相当于Linux系统中的tail命令 读取大小限制是2GB
     * @param filename 文件名
     * @param charset  文件编码格式,传null默认使用defaultCharset
     * @param rows     读取行数
     * @throws IOException IOException
  
   public
  
  
   static
  
  String
  
   readLastRows
  
  
   (
  
  String filename
  
   ,
  
  Charset charset
  
   ,
  
  
   int
  
  rows
  
   )
  
  
   throws
  
  IOException
  
   {
   
  
  charset
  
   =
  
  charset
  
   ==
  
  null
  
   ?
  
  Charset
  
   .
  
  
   defaultCharset
  
  
   (
  
  
   )
  
  
   :
  
  charset
  
   ;
  
  
   byte
  
  
   [
  
  
   ]
  
  lineSeparator
  
   =
  
  System
  
   .
  
  
   getProperty
  
  
   (
  
  
   "line.separator"
  
  
   )
  
  
   .
  
  
   getBytes
  
  
   (
  
  
   )
  
  
   ;
  
  
   try
  
  
   (
  
  RandomAccessFile rf
  
   =
  
  
   new
  
  
   RandomAccessFile
  
  
   (
  
  filename
  
   ,
  
  
   "r"
  
  
   )
  
  
   )
  
  
   {
   
  
  
  
   byte
  
  
   [
  
  
   ]
  
  c
  
   =
  
  
   new
  
  
   byte
  
  
   [
  
  lineSeparator
  
   .
  
  length
  
   ]
  
  
   ;
  
  
  
   for
  
  
   (
  
  
   long
  
  pointer
  
   =
  
  rf
  
   .
  
  
   length
  
  
   (
  
  
   )
  
  
   ,
  
  lineSeparatorNum
  
   =
  
  
   0
  
  
   ;
  
  pointer
  
   >=
  
  
   0
  
  
   &&
  
  lineSeparatorNum
  
   <
  
  rows
  
   ;
  
  
   )
  
  
   {
   
  
  
  rf
  
   .
  
  
   seek
  
  
   (
  
  pointer
  
   --
  
  
   )
  
  
   ;
  
  
  
   int
  
  readLength
  
   =
  
  rf
  
   .
  
  
   read
  
  
   (
  
  c
  
   )
  
  
   ;
  
  
   if
  
  
   (
  
  readLength
  
   !=
  
  
   -
  
  
   1
  
  
   &&
  
  Arrays
  
   .
  
  
   equals
  
  
   (
  
  lineSeparator
  
   ,
  
  c
  
   )
  
  
   )
  
  
   {
   
  
  lineSeparatorNum
  
   ++
  
  
   ;
  
  
  
   if
  
  
   (
  
  pointer
  
   ==
  
  
   -
  
  
   1
  
  
   &&
  
  lineSeparatorNum
  
   <
  
  rows
  
   )
  
  
   {
   
  
  rf
  
   .
  
  
   seek
  
  
   (
  
  
   0
  
  
   )
  
  
   ;
  
  
   byte
  
  
   [
  
  
   ]
  
  tempbytes
  
   =
  
  
   new
  
  
   byte
  
  
   [
  
  
   (
  
  
   int
  
  
   )
  
  
   (
  
  rf
  
   .
  
  
   length
  
  
   (
  
  
   )
  
  
   -
  
  rf
  
   .
  
  
   getFilePointer
  
  
   (
  
  
   )
  
  
   )
  
  
   ]
  
  
   ;
  
  rf
  
   .
  
  
   readFully
  
  
   (
  
  tempbytes
  
   )
  
  
   ;
  
  
   return
  
  
   new
  
  
   String
  
  
   (
  
  tempbytes
  
   ,
  
  charset
  
   )
  
  
   ;
  
  Java读取文件最后几行项目里需要读取最新的日志,可是最新的日志都在文件的最后几行,所以有了这个需求。百度之后先研究了别人的代码,感觉一是逻辑不太好理解,二是代码偏向于测试,没有办法哪来就用。所以自己写了这个方法,希望可以给看到的同学带来帮助。也算我自己的一点积累吧。	/**	 * 读取文件最后几行	 * @param filename	 * @param rows	 * @thr...
1、首先在pom
  
   文件
  
  导入依赖
<!--在
  
   Java
  
  中,我们可以使用 Apache Commons IO 的 ReversedLinesFileReader 类
  
   读取文件
  
  的
  
   最后
  
  几
  
   行
  
  。 -->
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
  
   最近线上有一个需求,下载系统日志,但是由于tomcat 日志比较大,超过 几百兆甚至几个G。如果用传统方法,将日志
   
    文件
   
   
    读取
   
   到内存,显然是有问题的。
下面提供一种 截取日志
   
    最后
   
   N
   
    行
   
   而不会导致内存溢出的方法。使用commons.io 包的ReversedLinesFileReader对象。
代码如下:
package ygw.study.play;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.input.R.
  
  
   当我们在
   
    读取文件
   
   的时候,通常都是从前向后
   
    读取
   
   ,那如果要
   
    读取文件
   
   的
   
    最后
   
   一
   
    行
   
   内容,要如何操作呢?
顺序遍历
   
    读取
   
   ,直到
   
    文件
   
   
    最后
   
   一
   
    行
   
   public static String readLastLineV0(File file) {
  String lastLine = "";
  try (BufferedReader bufferedReader = new BufferedReader(new FileReader(file))) {
    String currentLine = "";
   
    java
   
   动态获取
   
    文件
   
   某
   
    行
   
   内容的前几
   
    行
   
   ,就是当
   
    文件
   
   
    读取
   
   到该
   
    文件
   
   的某
   
    行
   
   内容时,动态获取该
   
    行
   
   内容的前几
   
    行
   
   ,这里由于业务需要动态获取当7
   
    行
   
   ,和后7
   
    行
   
   代码如下:
这里采用  RandomAccessFile 一
   
    行
   
   一
   
    行
   
   
    读取文件
   
   。
new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
    public static void main(String[] args) {
        //调用
   
    读取
   
   方法,定义
   
    文件
   
   以及
   
    读取
   
   
    行
   
   数
        List list = readLastNLine(new File("D:/1.txt"), 5L);
        if (list != null
  
  import
  
   java
  
  .io.FileNotFoundException;
import
  
   java
  
  .io.IOException;
import
  
   java
  
  .io.RandomAccessFile;
public class ReverseRead {