java异步写日志到文件中详解

实现代码:

package com.tydic.ESUtil;

import java.io.File;

import java.io.FileWriter;

import java.io.IOException;

import java.io.InputStream;

import java.io.PrintWriter;

import java.util.Properties;

public class LogWriter {

// 日志的配置文件

public static final String LOG_CONFIGFILE_NAME = "log.properties";

// 日志文件名在配置文件中的标签

public static final String LOGFILE_TAG_NAME = "logfile";

// 默认的日志文件的路径和文件名称

private final String DEFAULT_LOG_FILE_NAME = "./logtext.log";

// 该类的唯一的实例

private static LogWriter logWriter;

// 文件输出流

private PrintWriter writer;

// 日志文件名

private String logFileName;

/**

* 默认构造函数

*/

private LogWriter() throws LogException{

this.init();

}

private LogWriter(String fileName) throws LogException{

this.logFileName = fileName;

this.init();

}

/**

* 获取LogWriter的唯一实例。

* @return

* @throws LogException

*/

public synchronized static LogWriter getLogWriter()throws LogException{

if (logWriter == null){

logWriter = new LogWriter();

}

return logWriter;

}

public synchronized static LogWriter getLogWriter(String logFileName)throws LogException{

if (logWriter == null){

logWriter = new LogWriter(logFileName);

}

return logWriter;

}

/**

* 往日志文件中写一条日志信息

* 为了防止多线程同时操作(写)日志文件,造成文件”死锁”。使用synchronized关键字

* @param logMsg 日志消息

*/

public synchronized void log(String logMsg) {

this.writer.println(new java.util.Date() + ": " + logMsg);

}

/**

* 往日志文件中写一条异常信息

* 使用synchronized关键字。

* @param ex 待写入的异常

*/

public synchronized void log(Exception ex) {

writer.println(new java.util.Date() + ": ");

ex.printStackTrace(writer);

}

/**

* 初始化LogWriter

* @throws LogException

*/

private void init() throws LogException{

//如果用户没有在参数中指定日志文件名,则从配置文件中获取。

if (this.logFileName == null){

this.logFileName = this.getLogFileNameFromConfigFile();

//如果配置文件不存在或者也没有指定日志文件名,则用默认的日志文件名。

if (this.logFileName == null){

this.logFileName = DEFAULT_LOG_FILE_NAME;

}

}

File logFile = new File(this.logFileName);

try {

// 其中的FileWriter()中的第二个参数的含义是:是否在文件中追加内容

// PrintWriter()中的第二个参数的含义是:自动将数据flush到文件中

writer = new PrintWriter(new FileWriter(logFile, true), true);

System.out.println("日志文件的位置:" + logFile.getAbsolutePath());

} catch (IOException ex) {

String errmsg = "无法打开日志文件:" + logFile.getAbsolutePath();

// System.out.println(errmsg);

throw new LogException(errmsg, ex);

}

}

/**

* 从配置文件中取日志文件名

* @return

*/

private String getLogFileNameFromConfigFile() {

try {

Properties pro = new Properties();

//在类的当前位置,查找属性配置文件log.properties

InputStream fin = getClass().getResourceAsStream(LOG_CONFIGFILE_NAME);

if (fin != null){

pro.load(fin);//载入配置文件

fin.close();

return pro.getProperty(LOGFILE_TAG_NAME);

} else {

System.err.println("无法打开属性配置文件: log.properties" );

}

}catch (IOException ex) {

System.err.println("无法打开属性配置文件: log.properties" );

}

return null;

}

//关闭LogWriter

public void close() {

logWriter = null;

if (writer != null){

writer.close();

}

}

public static void main(String[] args) {

LogWriter logger = null;

try {

String fileName = "d:/temp/logger.log";

logger = LogWriter.getLogWriter(fileName);

// logger.log("First log!");

// logger.log("第二个日志信息");

// logger.log("Third log");

// logger.log("第四个日志信息");

String content="tableaA|device_number|13701010";

StringBuffer sb=new StringBuffer();

for(int i=0;i<1000000;i++){

sb.append(content).append(i).append(";\n");

}

content=sb.toString();

long startTime=System.currentTimeMillis();

logger.log(content);

long endTime=System.currentTimeMillis();

System.out.println("总消耗时间:"+(endTime-startTime));

logger.close();

// ReadFromFile.readFileByLines(fileName);

} catch (LogException e) {

e.printStackTrace();

}

}

}

package com.tydic.ESUtil;

public class AychWriter extends Thread {

private String content;

public AychWriter(String content){

this.content=content;

}

@Override

public void run(){

System.out.println("开始执行run()");

LogWriter logger = null;

String fileName = "d:/temp/logger.log";

long startTime=System.currentTimeMillis();

try {

logger = LogWriter.getLogWriter(fileName);

logger.log(this.content);

} catch (LogException e1) {

// TODO Auto-generated catch block

e1.printStackTrace();

}

long endTime=System.currentTimeMillis();

System.out.println("总消耗时间:"+(endTime-startTime));

}

}

测试类:

package com.tydic.ESUtil;

import java.io.FileWriter;

import java.io.IOException;

import org.junit.Test;

public class test_test {

/**

* 同步向指定文件尾部写入字符串

*/

public void testAppendMethodB(String fileName,String content) throws IOException{

try {

//打开一个写文件器,构造函数中的第二个参数true表示以追加形式写文件

FileWriter writer = new FileWriter(fileName, true);

writer.write(content);

writer.close();

} catch (IOException e) {

e.printStackTrace();

}

}

/**

*调用上面同步写方法

*/

@Test

public void testWriteTOFile() throws IOException{

String fileName = "d:\\test.txt";

String content="tableaA|device_number|13701010";

StringBuffer sb=new StringBuffer();

for(int i=0;i<100000;i++){

sb.append(content).append(i).append(";\n");

}

content=sb.toString();

long startTime=System.currentTimeMillis();

testAppendMethodB(fileName,content);

long endTime=System.currentTimeMillis();

System.out.println("总消耗时间:"+(endTime-startTime));

}

/**

* 异步调用写方法

* @throws IOException

* @throws InterruptedException

*/

@Test

public void testAsyncWriteTOFile() throws IOException, InterruptedException{

String fileName = "d:\\test.txt";

String content="tableaA|device_number|13701010";

StringBuffer sb=new StringBuffer();

for(int i=0;i<100000;i++){

sb.append(content).append(i).append(";\n");

}

content=sb.toString();

System.out.println("start write...");

new AychWriter(content).start();

System.out.println("write over...");

Thread.sleep(30000); //重要,如果主线程挂了,调用线程也停止了

System.out.println("main Thread over");

}

}

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

java 异步记录日志_java异步写日志到文件中实现代码相关推荐

  1. 将JSON对象带有格式的写出到文件中

    需求:将一个JSON对象写出到文件中,要求文件中的JSON数据带有简单的格式.代码的实现参考了Java算法中的栈处理括号匹配问题.好了,不多说了,下面是代码的实现. 代码: 1 package gem ...

  2. 统计java文件中的代码行数

    统计Java代码行数工具类  --  CodeCounterUtil.java 统计指定目录下的java文件中代码行数  --  public static int  getCodeNumFromFo ...

  3. 【C 语言】文件操作 ( 学生管理系统 | 命令行接收数据填充结构体 | 结构体写出到文件中 | 查询文件中的结构体数据 )

    文章目录 一.学生管理系统 二.代码示例 一.学生管理系统 前两篇博客 [C 语言]文件操作 ( 将结构体写出到文件中并读取结构体数据 | 将结构体数组写出到文件中并读取结构体数组数据 ) [C 语言 ...

  4. oracle crontab e,Linux运维知识之通过crontab -e编辑生成的定时任务,写在哪个文件中...

    本文主要向大家介绍了Linux运维知识之通过crontab -e编辑生成的定时任务,写在哪个文件中,通过具体的内容向大家展现,希望对大家学习Linux运维知识有所帮助. 环境描述: 操作系统:Red  ...

  5. 以命令行的格式读取音频文件信息,并将读取的内容写到输出文件中

    文章目录 c语言实现代码 运行结果 总结: 输入: wavinfo -i xxx.wav -o output.txt 输出:(格式规范)xxx=yyy rate(Hz)=16000 length=32 ...

  6. Ubuntu下如何将文件夹中图片索引写进txt文件中

    方法之一 sudo find dress/ -name *.jpg | cut -d '/' -f2-3 > train_dress.txt "find"后面跟的是当前文件下 ...

  7. java 异步读写_Java异步与AIO

    异步编程提供了一个非阻塞的,事件驱动的编程模型. 这种编程模型利用系统中多核执行任务来提供并行,因此提高了应用的吞吐率.Java异步编程通常需要使用Future,FutureTask和Callable ...

  8. java filter 回调_Java 异步回调机制实例分析

    Java 异步回调机制 一.什么是回调 回调,回调.要先有调用,才有调用者和被调用者之间的回调.所以在百度百科中是这样的: 软件模块之间总是存在着一定的接口,从调用方式上,可以把他们分为三类:同步调用 ...

  9. java 多异步调用_java 异步调用与多线程

    异步与多线程的区别 一.异步和多线程有什么区别?其实,异步是目的,而多 线程是实现这个目的的方法.异步是说,A发起一个操作后(一般都是比较耗时的操作,如果不耗时的操作 就没有必要异步了),可以继续自顾 ...

最新文章

  1. 谈谈Backlog梳理活动
  2. [云炬创业基础笔记] 第四章测试3
  3. 八十四、搜索框动画效果实现,React-Redux 进行应用数据的管理
  4. C语言试题六十五之请编写函数实现猴子吃桃问题
  5. 【数论】GCD SUM(P2398)
  6. css3浏览,css3支持哪些浏览器?
  7. php正则提取a,正则表达式 - php提取html中指定div下a标签的text和href问题
  8. 会计电算化常考题目二
  9. 《Cocos2D-x权威指南》——3.7 容器类
  10. 笔记-JavaWeb学习之旅4
  11. sklearn 中的 Pipeline 机制
  12. HDU 6182 2017广西邀请赛:A Math Problem
  13. 面试常见问题及回答技巧
  14. 【转载】DIY新浪微博Android手机客户端(一)(二)(三)完
  15. 怎么把图片的文字提取出来?
  16. 浏览器打开本地exe
  17. java 后台判断浏览器类型,IE11下载乱码解决方案
  18. 阿里、百度、华为都用什么编程语言?做程序员前,这些别说不知道!
  19. ios手机python编译器免费_适用与IOS手机的python编辑器,让你不限空间,地点都能玩转pyhton代码 !...
  20. 概率分布详解 Bernoulli、Binomial、Beta

热门文章

  1. Html中img自带属性有哪些,HTML IMG标签的属性是有哪些?了解IMG标签的用法
  2. MinGW离线安装包安装教程
  3. win7 计算机登录用户密码,win7系统忘记密码后强制登录系统的方法
  4. js读取json文件片段中的数据
  5. 微型计算机与商用机,可与手机协同办公,配备8核心处理器!首款华为商用台式机体验...
  6. 字节码插桩之Java Agent
  7. 创建文明校园争做文明学生PPT模板
  8. int与char[]的相互转换
  9. C++ ifndef /define/ endif 作用和用法
  10. java控制excel_利用Java控制EXCEL实例详解