/*
* Created on 2005-7-29 - 22:45:27 by jerry.li
* Filename is SimpleLog.java
*
* Any question,mailto fdabobi@gmail.com
*
* Use eclipse and default encoding ‘GBK‘
*/
package cn.zhuazi.util;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
/**
* 該類是一個(gè)簡(jiǎn)單的日志記錄器,按日期生成日志文件
* @author Administrator
*
*/
public class SimpleLog {
/** 默認(rèn)文件名 */
protected static final String DEFAULT_NAME = "MyLog";
/** 默認(rèn)存儲(chǔ)方式 */
protected static final boolean DEFAULT_METHOD = false;
/** 默認(rèn)緩存大小 */
protected static final int DEFAULT_SIZE = 10;
/** 日志間的分隔符 */
protected static final String SEP = "\n";
/** 緩存大小 */
protected int messageSize = 0;
/** 文件前綴 */
protected String fileName = null;
/** 當(dāng)前文件名,不含.log */
protected String currentLogFile = "";
/** 當(dāng)前是否使用緩存 */
protected boolean bufferMethod = DEFAULT_METHOD;
/** 以 List 實(shí)現(xiàn)的緩存 */
protected List bufferedMessage;
/**
* 默認(rèn)構(gòu)造函數(shù),使用默認(rèn)值構(gòu)造日志記錄器
*/
public SimpleLog(){
init(DEFAULT_NAME,DEFAULT_SIZE,DEFAULT_METHOD);
}
/**
* 指定文件前綴與緩存大小,緩存將自動(dòng)啟用
* @param fileName 文件前綴,不含日期
* @param bufferSize 緩存大小 10~200,超過200以200計(jì),低與10以10計(jì)
*/
public SimpleLog(String fileName,int bufferSize){
bufferSize = (bufferSize >= 10 && bufferSize <= 200) ?
bufferSize : ((bufferSize > 200) ? 200 : 10);
init(fileName,bufferSize,true);
}
/**
* 指定文件前綴與是否啟用緩存,緩存將使用默認(rèn)值: <code>{@link #DEFAULT_METHOD}</code>
* @param fileName
* @param bufferMethod
*/
public SimpleLog(String fileName,boolean bufferMethod){
init(fileName,DEFAULT_SIZE,true);
}
/**
* 根據(jù)指定參數(shù)初始化實(shí)例,并計(jì)算當(dāng)前文件名
* @param fileName 文件前綴
* @param bufferSize 緩存大小
* @param bufferMethod 是否啟用緩存
*/
protected void init(String fileName,int bufferSize,boolean bufferMethod){
this.messageSize = bufferSize;
this.fileName = fileName;
this.bufferMethod = bufferMethod;
if (bufferMethod){
this.bufferedMessage = Collections.synchronizedList(new ArrayList());
}
//先計(jì)算文件名
this.currentLogFile = this.fileName + this.getDateString();
}
/**
* 處理日志信息,判斷<code>{@link #bufferMethod}</code>,<br/>
* true : 將日志緩存,直到緩存超出<code>{@link #messageSize}</code>,則追加到文件尾部<br/>
* false : 將日志直接追加到文件尾部<br>
* <b>注意</b> : 緩存模式中,請(qǐng)?jiān)趹?yīng)用程序退出前調(diào)用<code>{@link #forceClearBufferAtOnce()}</code>提交<br>,
* 否則緩存中未及時(shí)保存的信息將丟失
* @param message 要保存的信息
* @return true保存成功 false保存失敗
*/
public synchronized boolean processLog(String message){
String tempName = this.fileName + getDateString();
// 生成文件名并判斷是否日期已經(jīng)更換
if (!currentLogFile.equals(tempName)){
if (bufferMethod)
{
// 日期更換則先強(qiáng)行提交
try {
forceClearBufferAtOnce();
} catch (Exception e) {
// 忽略錯(cuò)誤
}
}
// 文件名替換
currentLogFile = tempName;
}
// 根據(jù)記錄模式選擇對(duì)應(yīng)的記錄方式
try {
if (bufferMethod){
processLogWithBuffer(message,false);
}else{
processLogAtOnce(message);
}
} catch (IOException e) {
// 保存過程捕捉到錯(cuò)誤
return false;
}
// 準(zhǔn)確完成
return true;
}
/**
* 將消息立即保存到以<code>{@link #currentLogFile}</code>命名的.log文件,<br/>
* 使用 java.io.RandomAccessFile 進(jìn)行保存,并且以插入分隔符 <code>{@link #SEP}</code>
* @param message
* @throws IOException 保存失敗時(shí)拋出
*/
protected void processLogAtOnce(String message) throws IOException{
File currentFile = new File(currentLogFile + ".log");
if (!currentFile.exists()){
currentFile.createNewFile();
}
//FileWriter out = new FileWriter(currentFile);
RandomAccessFile out = new RandomAccessFile(currentFile,"rw");
out.seek(out.length());
out.writeBytes(SEP);
out.write(message.getBytes());
out.close();
}
/**
* 將消息保存到 <code>{@link #bufferedMessage}</code> ,直到緩存達(dá)到指定數(shù),<br/>
* 使用<code> {@link #processLogAtOnce(String)}</code> 立即保存消息<br/>
* @param message
* @param force 忽略緩存大小,強(qiáng)制保存
* @throws IOException 保存失敗時(shí)拋出
*/
protected synchronized void processLogWithBuffer(String message,boolean force) throws IOException{
// 先保存消息
if (message != null){
bufferedMessage.add(message);
}
// 判斷是否需要立即保存到文件
if (force || bufferedMessage.size() >= messageSize){
StringBuffer sb = new StringBuffer();
Iterator it = bufferedMessage.iterator();
if (it.hasNext()){
do {
sb.append(SEP + it.next());
} while (it.hasNext());
}
/*if (force){
System.out.println("Save at once cause force!");
}else{
System.out.println("Save at once cause buffer full!");
}*/
//截取字符串首個(gè)分隔符,因?yàn)橄到y(tǒng)自動(dòng)會(huì)在消息前加
processLogAtOnce(sb.substring(SEP.length()));
bufferedMessage.clear();
}
}
/**
* 強(qiáng)制將緩存中的消息保存到文件
* @return true保存成功 false保存失敗
* @throws Exception 非緩存模式
*/
public boolean forceClearBufferAtOnce() throws Exception{
if (!bufferMethod){
throw new Exception("Not buffer model, can‘t force clear!");
}
try {
processLogWithBuffer(null,true);
} catch (IOException e) {
return false;
}
return true;
}
/**
* TODO 以更好的算法替換每次記錄都判斷時(shí)間<br/>
*
* 獲取日期字符串,不包含時(shí)間
* @return 表示日期的字符串
*/
protected String getDateString(){
String date = new Date().toLocaleString();
return date.substring(0,date.indexOf(" "));
}
public static void main(String[] args) throws Exception{
System.out.println("not buffer model start!");
SimpleLog log = new SimpleLog();
Date d1 = new Date();
for (int i = 0; i < 30 ; ++ i){
log.processLog("哈哈,This is my log, number : " + i);
}
Date d2 = new Date();
System.out.println("not buffer model over! Time : " + (d2.getTime() - d1.getTime()));
System.out.println("buffer model start!");
log = new SimpleLog("YourLog",25);
Date d3 = new Date();
for (int i = 0; i < 30 ; ++ i){
log.processLog("哈哈,This is my log, number : " + i);
}
log.forceClearBufferAtOnce();
Date d4 = new Date();
System.out.println("buffer model over! Time : " + (d4.getTime() - d3.getTime()));
String date = d4.toLocaleString();
File f1 = new File("MyLog" + date.substring(0,date.indexOf(" ")) + ".log");
File f2 = new File("YourLog" + date.substring(0,date.indexOf(" ")) + ".log");
FileReader read1 = new FileReader(f1);
FileReader read2 = new FileReader(f2);
BufferedReader br1 = new BufferedReader(read1);
BufferedReader br2 = new BufferedReader(read2);
String str = null;
while ((str = br1.readLine()) != null){
System.out.println((str));
}
while ((str = br2.readLine()) != null){
System.out.println((str));
}
}
}
聯(lián)系客服