当前位置:首页 > 文章列表 > 文章 > java教程 > Java Tailer从文件开头和末尾读取有什么区别

Java Tailer从文件开头和末尾读取有什么区别

来源:17golang原创 2026-10-13 19:42:53 0浏览 收藏

我第一次把 Apache Commons IO 的 Tailer 接到应用日志上时,最容易混淆的是“从文件开头读”和“从文件末尾开始等”这两个选择。它们不是读取速度不同,而是决定启动时要不要把已经存在的历史内容交给监听器。官方地址:https://commons.apache.org/。

需要补处理启动前已经写入的日志,就从文件开头读取;只关心启动后的新增日志,就从当前末尾开始。旧式 API 的 end=false 对应开头,end=true 对应末尾,新代码可用 Builder 的 setTailFromEnd 表达同样的意思。

先判断是补读历史还是只接收新增内容

可以把 Tailer 想成一个持续观察文件的读取器。选择从开头读取时,文件当前已经存在的每一行都可能依次触发 TailerListener.handle(String line),读到当前末尾后再等待后续内容;选择从末尾开始时,启动前的旧行不会被当作本次监听事件,读取位置直接落在文件当前末尾。

这决定了适用场景:启动后要重建一段短时间窗口,使用开头模式;监控进程只需要接收新的错误行,使用末尾模式。末尾模式不是“读取最后一行”,也不是从文件末尾向前倒序扫描,它仍然按正常追加方向等待新内容。

Java Tailer 从文件开头和当前末尾读取的静态结构说明图
图1:Tailer 起始位置与监听回调的结构说明图,不是运行截图。

用 Builder 表达 Tailer 起始位置

Commons IO 新版 API 推荐使用 Builder。下面的两个配置只有起始位置不同,监听器、文件和轮询间隔仍然可以保持一致:

import java.io.File;
import java.time.Duration;
import org.apache.commons.io.input.Tailer;
import org.apache.commons.io.input.TailerListenerAdapter;

// 监听器只展示收到的行;生产代码应在 handle 中完成限流或投递队列
TailerListenerAdapter listener = new TailerListenerAdapter() {
    @Override
    public void handle(String line) {
        System.out.println(line);
    }
};

Tailer tailer = Tailer.builder()
    .setFile(new File("app.log"))
    .setTailerListener(listener)
    .setDelayDuration(Duration.ofSeconds(1))
    // false:从文件开头;true:跳到当前末尾后等待新增内容
    .setTailFromEnd(false)
    .get();

如果改成 true,Tailer 会把启动点放在当前末尾。这里的布尔值只描述启动时的读取位置,不会保存上一次进程退出时的偏移量;要做可靠断点续读,仍需业务层保存偏移、文件标识和轮转策略。

处理文件轮转、找不到文件和停止

日志轮转是另一个容易被误判的地方。Tailer 发现文件被替换或截断时,会通过 fileRotated() 通知监听器,并尝试重新打开资源;新文件尚未出现时,还可能收到 fileNotFound()。这些回调描述文件资源状态,不会把“从末尾启动”自动升级为“从旧文件的最后偏移继续”。

TailerListenerAdapter listener = new TailerListenerAdapter() {
    @Override
    public void fileRotated() {
        // 轮转只说明资源边界变化,是否补读新文件由业务规则决定
        System.out.println("log file rotated");
    }

    @Override
    public void fileNotFound() {
        // 文件暂时不存在时保留可观测信息,避免把等待误报成业务异常
        System.out.println("log file is not available");
    }

    @Override
    public void handle(Exception ex) {
        // 回调线程中的异常要记录或转交,不要静默吞掉
        ex.printStackTrace();
    }
};

// close 会请求 Tailer 完成本轮检查后结束;不再需要时要主动关闭
tailer.close();
Java Tailer 文件轮转和生命周期回调的静态结构说明图
图2:Tailer 文件轮转与生命周期回调的边界结构说明图,不是运行截图。

按版本选择 API 并做场景取舍

官方 API 中,带 end 参数的旧构造器和 create 方法仍能帮助理解历史代码:false 是从开头,true 是从末尾。不过这些入口在较新的 Commons IO 文档中已标记为 deprecated,新代码优先使用 Builder,可以把文件、监听器、延迟、重开行为和起始位置写成具名配置。

目标起始配置启动时的内容注意点
补读历史并继续跟读setTailFromEnd(false)已有内容会触发回调历史量大时要考虑消费速度和背压
只监听新增日志setTailFromEnd(true)跳过启动前内容不等于断点续读,轮转要另定策略

我实际选择时会先问一个问题:这次启动是否对之前的日志负有处理责任?如果答案是“有”,用开头模式并限制历史范围;如果答案是“没有”,用末尾模式减少重复消费。无论哪种模式,都要让 close() 进入应用的关闭流程。

相关问题

Tailer 的 end=true 是倒序读取吗?不是。它只把启动位置放到当前文件末尾,后续仍等待文件追加的新行。

setTailFromEnd(true) 能实现断点续读吗?不能。断点续读需要业务层保存文件身份和偏移,并处理截断、替换与重复投递。

文件轮转后会自动从新文件开头读取吗?不能只凭起始配置下结论。轮转和文件缺失通过监听器回调暴露,是否补读新文件应由业务策略决定。

版本声明
本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
Java StringSubstitutor怎样为缺失变量提供默认值Java StringSubstitutor怎样为缺失变量提供默认值
上一篇
Java StringSubstitutor怎样为缺失变量提供默认值
Java Commons IO Tailer怎样跟踪日志文件轮转
下一篇
Java Commons IO Tailer怎样跟踪日志文件轮转
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    543次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    516次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    500次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    485次学习
查看更多
AI推荐
  • PubMedQA数据集详解:生物医学问答基准、功能与应用指南
    PubMedQA
    深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
    463次使用
  • H2O EvalGPT:开源LLM大模型评估与排行榜工具
    H2O EvalGPT
    H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
    526次使用
  • LMArena是什么?伯克利AI模型评估平台使用指南与功能解析
    LMArena
    LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
    543次使用
  • 斯坦福HELM:大语言模型Holistic Evaluation整体评估框架详解
    HELM
    深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
    491次使用
  • MMBench详解:多模态大模型基准测试、功能特点与使用指南
    MMBench
    MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
    310次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议 和 隐私政策
返回登录
  • 重置密码