java异步写日志到文件中实现代码

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");
  } 

}

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

(0)

相关推荐

  • java异步写日志到文件中实现代码

    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 { // 日志的配置文件 publi

  • c# 编写一个轻量级的异步写日志的实用工具类(LogAsyncWriter)

    一说到写日志,大家可能推荐一堆的开源日志框架,如:Log4Net.NLog,这些日志框架确实也不错,比较强大也比较灵活,但也正因为又强大又灵活,导致我们使用他们时需要引用一些DLL,同时还要学习各种用法及配置文件,这对于有些小工具.小程序.小网站来说,有点"杀鸡焉俺用牛刀"的感觉,而且如果对这些日志框架不了解,可能输出来的日志性能或效果未毕是与自己所想的,鉴于这几个原因,我自己重复造轮子,编写了一个轻量级的异步写日志的实用工具类(LogAsyncWriter),这个类还是比较简单的,实

  • java使用OpenCV从视频文件中获取帧

    本文实例为大家分享了java使用OpenCV从视频文件中获取帧的具体代码,供大家参考,具体内容如下 实现功能:使用Java获取mp4.mov.avi等视频文件中的图像帧,每秒获取一帧图像,并保存 环境要求:需要安装Opencv,安装FFmpeg,下载javacv包 操作系统:本次实验使用的Ubuntu系统 实验代码 import com.googlecode.javacv.cpp.opencv_highgui; import org.opencv.core.Core; import org.op

  • 利用Python如何将数据写到CSV文件中

    前言 我们从网上爬取数据,最后一步会考虑如何存储数据.如果数据量不大,往往不会选择存储到数据库,而是选择存储到文件中,例如文本文件.CSV 文件.xls 文件等.因为文件具备携带方便.查阅直观. Python 作为胶水语言,搞定这些当然不在话下.但在写数据过程中,经常因数据源中带有中文汉字而报错.最让人头皮发麻的编码问题. 我先说下编码相关的知识.编码方式有很多种:UTF-8, GBK, ASCII 等. ASCII 码是美国在上个世纪 60 年代制定的一套字符编码.主要是规范英语字符和二进制位

  • golang xorm日志写入文件中的操作

    golang访问数据库记录SQL语句: 使用的包为: 1:github.com/arthurkiller/rollingwriter //写入日志包 2: github.com/go-xorm/xorm //xorm包 具体实现为: package main import ( "time" "github.com/arthurkiller/rollingwriter" _ "github.com/go-sql-driver/mysql" &quo

  • Java使用sftp定时下载文件的示例代码

    sftp简介 sftp是Secure File Transfer Protocol的缩写,安全文件传送协议.可以为传输文件提供一种安全的网络的加密方法.sftp 与 ftp 有着几乎一样的语法和功能.SFTP 为 SSH的其中一部分,是一种传输档案至 Blogger 伺服器的安全方式.其实在SSH软件包中,已经包含了一个叫作SFTP(Secure File Transfer Protocol)的安全文件信息传输子系统,SFTP本身没有单独的守护进程,它必须使用sshd守护进程(端口号默认是22)

  • Java使用poi导出ppt文件的实现代码

    什么是poi Apache POI 是用Java编写的免费开源的跨平台的 Java API,Apache POI提供API给Java程式对Microsoft Office格式档案读和写的功能.POI为"Poor Obfuscation Implementation"的首字母缩写,意为"简洁版的模糊实现". poi常用的包 HSSF  - 提供读写Microsoft Excel XLS格式档案的功能. XSSF  - 提供读写Microsoft Excel OOXML

  • Java手写持久层框架的详细代码

    目录 前言 JDBC操作回顾及问题分析 1.定义配置xml文件 2.读取配置文件 3.定义sql操作接口SqlSession 4.编写数据库执行逻辑 5.调用测试 ⾃定义框架优化 总结 本文适合有一定java基础的同学,通过分析jdbc存在的问题,进行手写自定义持久层框架,可以更加清楚常用的mybatis等开源框架的原理. 前言 本文适合有一定java基础的同学,通过自定义持久层框架,可以更加清楚常用的mybatis等开源框架的原理. JDBC操作回顾及问题分析 学习java的同学一定避免不了接

  • Java实现图片转换PDF文件的示例代码

    最近因为一些事情,需要将一张简单的图片转换为PDF的文件格式,在网上找了一些工具,但是这些工具不是需要注册账号,就是需要下载软件. 而对于只是转换一张图片的情况下,这些操作显然是非常繁琐的,所以作者就直接使用Java写了一个图片转换PDF的系统,现在将该系统分享在这里. 引入依赖 <!--该项目以SpringBoot为基础搭建--> <parent> <groupId>org.springframework.boot</groupId> <artifa

  • 如何利用python执行txt文件中的代码

    目录 前言: 1.什么是exec()函数? 2.如何将txt中的代码作为字符串读取? 3.使用exec()执行txt文件的完整例子 前言: 我们知道,python代码文件大多数都是py类型. 那么,能不能使用txt文件存储我们的代码呢? python这么强大的语言当然可以做大,只需使用内置的exex()函数. 1.什么是exec()函数? 根据官方文档的介绍,exec函数的定义如下: exec(source, globals=None, locals=None, /)     Execute t

随机推荐