这里有新鲜出炉的 Java 并发编程示例,程序狗速度看过来!
java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的 Java 程序设计语言和 Java 平台(即 JavaEE(j2ee), JavaME(j2me), JavaSE(j2se))的总称。
这篇文章主要给大家介绍了关于 Java 实时监控日志文件并输出的方法,文中通过示例代码介绍的非常详细,对大家具有一定的参考学习价值,需要的朋友们下面跟着小编一起来学习学习吧。
前言
最近有一个银行数据漂白系统, 要求操作人员在页面调用远端 Linux 服务器的 shell, 并将 shell 输出的信息保存到一个日志文件, 前台页面要实时显示日志文件的内容. 这个问题难点在于如何判断哪些数据是新增加的, 通过查看 JDK 的帮助文档,
可以解决这个问题. 为了模拟这个问题, 编写 LogSvr 和 LogView 类, LogSvr 不断向 mock.log 日志文件写数据, 而 LogView 则实时输出日志变化部分的数据.
- java.io.RandomAccessFile
代码 1: 日志产生类
- package com.bill99.seashell.domain.svr;
- import java.io.File;
- import java.io.FileWriter;
- import java.io.IOException;
- import java.io.Writer;
- import java.text.SimpleDateFormat;
- import java.util.Date;
- import java.util.concurrent.Executors;
- import java.util.concurrent.ScheduledExecutorService;
- import java.util.concurrent.TimeUnit;
- /**
- *<p>title: 日志服务器</p>
- *<p>Description: 模拟日志服务器</p>
- *<p>CopyRight: CopyRight (c) 2010</p>
- *<p>Company: 99bill.com</p>
- *<p>Create date: 2010-6-18</P>
- *@author Tank Zhang<tank.zhang@99bill.com>
- *@version v0.1 2010-6-18
- */
- public class LogSvr {
- private SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
- /**
- * 将信息记录到日志文件
- * @param logFile 日志文件
- * @param mesInfo 信息
- * @throws IOException
- */
- public void logMsg(File logFile, String mesInfo) throws IOException {
- if (logFile == null) {
- throw new IllegalStateException("logFile can not be null!");
- }
- Writer txtWriter = new FileWriter(logFile, true);
- txtWriter.write(dateFormat.format(new Date()) + "\t" + mesInfo + "\n");
- txtWriter.flush();
- }
- public static void main(String[] args) throws Exception {
- final LogSvr logSvr = new LogSvr();
- final File tmpLogFile = new File("mock.log");
- if (!tmpLogFile.exists()) {
- tmpLogFile.createNewFile();
- }
- //启动一个线程每5秒钟向日志文件写一次数据
- ScheduledExecutorService exec = Executors.newScheduledThreadPool(1);
- exec.scheduleWithFixedDelay(new Runnable() {
- public void run() {
- try {
- logSvr.logMsg(tmpLogFile, " 99bill test !");
- } catch(IOException e) {
- throw new RuntimeException(e);
- }
- }
- },
- 0, 5, TimeUnit.SECONDS);
- }
- }
代码 2: 显示日志的类
- package com.bill99.seashell.domain.client;
- import java.io.File;
- import java.io.IOException;
- import java.io.RandomAccessFile;
- import java.util.concurrent.Executors;
- import java.util.concurrent.ScheduledExecutorService;
- import java.util.concurrent.TimeUnit;
- public class LogView {
- private long lastTimeFileSize = 0; //上次文件大小
- /**
- * 实时输出日志信息
- * @param logFile 日志文件
- * @throws IOException
- */
- public void realtimeShowLog(File logFile) throws IOException {
- //指定文件可读可写
- final RandomAccessFile randomFile = new RandomAccessFile(logFile, "rw");
- //启动一个线程每10秒钟读取新增的日志信息
- ScheduledExecutorService exec = Executors.newScheduledThreadPool(1);
- exec.scheduleWithFixedDelay(new Runnable() {
- public void run() {
- try {
- //获得变化部分的
- randomFile.seek(lastTimeFileSize);
- String tmp = "";
- while ((tmp = randomFile.readLine()) != null) {
- System.out.println(new String(tmp.getBytes("ISO8859-1")));
- }
- lastTimeFileSize = randomFile.length();
- } catch(IOException e) {
- throw new RuntimeException(e);
- }
- }
- },
- 0, 1, TimeUnit.SECONDS);
- }
- public static void main(String[] args) throws Exception {
- LogView view = new LogView();
- final File tmpLogFile = new File("mock.log");
- view.realtimeShowLog(tmpLogFile);
- }
- }
执行 LogSvr 类, LogSvr 类会启动一个线程, 每 5 秒钟向 mock.log 日志文件写一次数据, 然后再执行 LogView 类, LogView 每隔 1 秒钟读一次, 如果数据有变化则输出变化的部分.
结果输出:
- 2010-06-19 17:25:54 99bill test !
- 2010-06-19 17:25:59 99bill test !
- 2010-06-19 17:26:04 99bill test !
- 2010-06-19 17:26:09 99bill test !
- 2010-06-19 17:26:14 99bill test !
- 2010-06-19 17:26:19 99bill test !
PS:
代码修改过, 有朋友下载了我的代码, 说如果是中文会乱码, 将日志输出类的第 30 行的代码
改成
- System.out.println(tmp)
, 就会正常显示中文.
- System.out.println(new String(tmp.getBytes("ISO8859-1")))
总结
来源: http://www.phperz.com/article/17/0818/338198.html