项目里需要读取最新的日志,可是最新的日志都在文件的最后几行,所以有了这个需求。
百度之后先研究了别人的代码,感觉一是逻辑不太好理解且注释比较少,二是代码偏向于演示,会有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 {