java異步寫(xiě)日志到文件中實(shí)現(xiàn)代碼
更新時(shí)間:2017年04月24日 11:19:10 作者:nature_fly088
這篇文章主要介紹了java異步寫(xiě)日志到文件中實(shí)現(xiàn)代碼的相關(guān)資料,需要的朋友可以參考下
java異步寫(xiě)日志到文件中詳解
實(shí)現(xiàn)代碼:
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";
// 日志文件名在配置文件中的標(biāo)簽
public static final String LOGFILE_TAG_NAME = "logfile";
// 默認(rèn)的日志文件的路徑和文件名稱(chēng)
private final String DEFAULT_LOG_FILE_NAME = "./logtext.log";
// 該類(lèi)的唯一的實(shí)例
private static LogWriter logWriter;
// 文件輸出流
private PrintWriter writer;
// 日志文件名
private String logFileName;
/**
* 默認(rèn)構(gòu)造函數(shù)
*/
private LogWriter() throws LogException{
this.init();
}
private LogWriter(String fileName) throws LogException{
this.logFileName = fileName;
this.init();
}
/**
* 獲取LogWriter的唯一實(shí)例。
* @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;
}
/**
* 往日志文件中寫(xiě)一條日志信息
* 為了防止多線程同時(shí)操作(寫(xiě))日志文件,造成文件”死鎖”。使用synchronized關(guān)鍵字
* @param logMsg 日志消息
*/
public synchronized void log(String logMsg) {
this.writer.println(new java.util.Date() + ": " + logMsg);
}
/**
* 往日志文件中寫(xiě)一條異常信息
* 使用synchronized關(guān)鍵字。
* @param ex 待寫(xiě)入的異常
*/
public synchronized void log(Exception ex) {
writer.println(new java.util.Date() + ": ");
ex.printStackTrace(writer);
}
/**
* 初始化LogWriter
* @throws LogException
*/
private void init() throws LogException{
//如果用戶沒(méi)有在參數(shù)中指定日志文件名,則從配置文件中獲取。
if (this.logFileName == null){
this.logFileName = this.getLogFileNameFromConfigFile();
//如果配置文件不存在或者也沒(méi)有指定日志文件名,則用默認(rèn)的日志文件名。
if (this.logFileName == null){
this.logFileName = DEFAULT_LOG_FILE_NAME;
}
}
File logFile = new File(this.logFileName);
try {
// 其中的FileWriter()中的第二個(gè)參數(shù)的含義是:是否在文件中追加內(nèi)容
// PrintWriter()中的第二個(gè)參數(shù)的含義是:自動(dòng)將數(shù)據(jù)flush到文件中
writer = new PrintWriter(new FileWriter(logFile, true), true);
System.out.println("日志文件的位置:" + logFile.getAbsolutePath());
} catch (IOException ex) {
String errmsg = "無(wú)法打開(kāi)日志文件:" + logFile.getAbsolutePath();
// System.out.println(errmsg);
throw new LogException(errmsg, ex);
}
}
/**
* 從配置文件中取日志文件名
* @return
*/
private String getLogFileNameFromConfigFile() {
try {
Properties pro = new Properties();
//在類(lèi)的當(dāng)前位置,查找屬性配置文件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("無(wú)法打開(kāi)屬性配置文件: log.properties" );
}
}catch (IOException ex) {
System.err.println("無(wú)法打開(kāi)屬性配置文件: log.properties" );
}
return null;
}
//關(guān)閉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("第二個(gè)日志信息");
// logger.log("Third log");
// logger.log("第四個(gè)日志信息");
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("總消耗時(shí)間:"+(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("開(kāi)始執(zhí)行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("總消耗時(shí)間:"+(endTime-startTime));
}
}
測(cè)試類(lèi):
package com.tydic.ESUtil;
import java.io.FileWriter;
import java.io.IOException;
import org.junit.Test;
public class test_test {
/**
* 同步向指定文件尾部寫(xiě)入字符串
*/
public void testAppendMethodB(String fileName,String content) throws IOException{
try {
//打開(kāi)一個(gè)寫(xiě)文件器,構(gòu)造函數(shù)中的第二個(gè)參數(shù)true表示以追加形式寫(xiě)文件
FileWriter writer = new FileWriter(fileName, true);
writer.write(content);
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
*調(diào)用上面同步寫(xiě)方法
*/
@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("總消耗時(shí)間:"+(endTime-startTime));
}
/**
* 異步調(diào)用寫(xiě)方法
* @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); //重要,如果主線程掛了,調(diào)用線程也停止了
System.out.println("main Thread over");
}
}
感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!
相關(guān)文章
Java多線程Future松獲取異步任務(wù)結(jié)果輕松實(shí)現(xiàn)
這篇文章主要為大家介紹了Java多線程Future松獲取異步任務(wù)結(jié)果輕松實(shí)現(xiàn)方法,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-04-04
詳解 Java繼承關(guān)系下的構(gòu)造方法調(diào)用
這篇文章主要介紹了詳解 Java繼承關(guān)系下的構(gòu)造方法調(diào)用的相關(guān)資料,希望通過(guò)本文能幫助到大家,讓大家理解掌握這部分內(nèi)容,需要的朋友可以參考下2017-10-10
Java中對(duì)list元素進(jìn)行排序的方法詳解
這篇文章主要介紹了Java中對(duì)list元素進(jìn)行排序的方法詳解,是Java入門(mén)學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下2015-09-09
詳解Java如何實(shí)現(xiàn)數(shù)值校驗(yàn)的算法
給定一個(gè)字符串如何判斷它是否為數(shù)值類(lèi)型?本文將帶著大家學(xué)習(xí)一下如何利用Java實(shí)現(xiàn)這個(gè)判斷算法,感興趣的小伙伴可以學(xué)習(xí)一下2022-04-04
JAVA實(shí)現(xiàn)長(zhǎng)連接(含心跳檢測(cè)Demo)
這篇文章主要介紹了JAVA實(shí)現(xiàn)長(zhǎng)連接(含心跳檢測(cè)Demo),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-10-10
SpringCloud Alibaba Seata (收藏版)
Seata是一款開(kāi)源的分布式事務(wù)解決方案,致力于在微服務(wù)架構(gòu)在提供高性能和簡(jiǎn)單一樣的分布式事務(wù)服務(wù)。這篇文章主要介紹了SpringCloud Alibaba Seata 的相關(guān)知識(shí),需要的朋友可以參考下2020-10-10

