最近线上有一个需求,下载系统日志,但是由于tomcat 日志比较大,超过 几百兆甚至几个G。如果用传统方法,将日志文件读取到内存,显然是有问题的。
下面提供一种 截取日志最后N行而不会导致内存溢出的方法。使用 commons.io 包的ReversedLinesFileReader对象。
代码如下:
package ygw.study.play;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.input.ReversedLinesFileReader;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* <p>
* 文件工具类
* </p>
* <p>
* Copyright:.All rights reserved.
* </p>
* <p>
* Company:Zsoft
* </p>
* <p>
* CreateDate: 2022-05-01
* </p>
*
* @author YuGongWen
* @history Mender: YuGongWen;Date: 2022-05-01;
*/
public class MyFileUtils {
public static void main(String[] args) {
String inPath = "C:\\aaa\\catalina.out";
String outPath = "C:\\aaa\\catalina-" + System.currentTimeMillis() + ".out";
getLastLogByFile(new File(inPath),new File(outPath),500);
}
public static void getLastLogByFile(File fileOrg, File outFile, int lines) {
try {
ReversedLinesFileReader reader = new ReversedLinesFileReader(fileOrg, Charset.defaultCharset());
List<String> lastNLogLines = getLastNLogLines(reader, lines);
Collections.reverse(lastNLogLines);// 将文本倒转
FileUtils.writeLines(outFile, lastNLogLines, false);
} catch (Exception e) {
e.printStackTrace();
}
}
public static List<String> getLastNLogLines(ReversedLinesFileReader reader, int nLines) throws IOException {
List<String> lastNLogLines = new ArrayList<>();
int counter = 0;
while (counter < nLines) {
lastNLogLines.add(reader.readLine());
counter++;
}
return lastNLogLines;
}
}
需要引入jar
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.11.0</version>
</dependency>