添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接


读取文件最后n行

方案1:指定编码格式(推荐)

代码

public class ReadFile {
public static void main(String[] args) {
//调用读取方法,定义文件以及读取行数
List<String> list = readLastNLine(new File("D:/1.txt"), 5L);
if (list != null) {
for (String str : list) {
System.out.println(str + "<br>");
}
}
}

/**
* 读取文件最后N行
* <p>
* 根据换行符判断当前的行数,
* 使用统计来判断当前读取第N行
* <p>
* PS:输出的List是倒叙,需要对List反转输出
*
* @param file 待文件
* @param numRead 读取的行数
* @return List<String>
*/
public static List<String> readLastNLine(File file, long numRead) {
// 定义结果集
List<String> result = new ArrayList<String>();
//行数统计
long count = 0;

// 排除不可读状态
if (!file.exists() || file.isDirectory() || !file.canRead()) {
return null;
}

// 使用随机读取
RandomAccessFile fileRead = null;
try {
//使用读模式
fileRead = new RandomAccessFile(file, "r");
//读取文件长度
long length = fileRead.length();
//如果是0,代表是空文件,直接返回空结果
if (length == 0L) {
return result;
} else {
//初始化游标
long pos = length - 1;
while (pos > 0) {
pos--;
//开始读取
fileRead.seek(pos);
//如果读取到\n代表是读取到一行
if (fileRead.readByte() == '\n') {
//使用readLine获取当前行
String line = new String(fileRead.readLine().getBytes("ISO-8859-1"), "utf-8");
//保存结果
result.add(line);

//打印当前行
//System.out.println(line);

//行数统计,如果到达了numRead指定的行数,就跳出循环
count++;
if (count == numRead) {
break;
}
}
}
if (pos == 0) {
fileRead.seek(0);
result.add(fileRead.readLine());
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fileRead != null) {
try {
//关闭资源
fileRead.close();
} catch (Exception e) {
}
}
}
Collections.reverse(result);
return result;
}
}

方案2:使用系统编码格式(不推荐)

其他网址

代码

public static String readLastRows(String filePath, int rows) throws IOException {
Charset charset = Charset.defaultCharset();
try (RandomAccessFile rf = new RandomAccessFile(filePath, "r")) {
// 每次读取的字节数要和系统换行符大小一致
byte[] c = new byte[1];
// 在获取到指定行数和读完文档之前,从文档末尾向前移动指针,遍历文档每一个字节
for (long pointer = rf.length(), lineSeparatorNum = 0; pointer >= 0 && lineSeparatorNum < rows;) {
// 移动指针
rf.seek(pointer--);
// 读取数据
int readLength = rf.read(c);
if (readLength != -1 && c[0] == 10) {
lineSeparatorNum++;
}
// 扫描完依然没有找到足够的行数,将指针归0
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);
}
}