工具介绍
使用了很多的日志工具,感觉配置比较麻烦,如果只是在控制台打印信息,和把信息保存在一个文件里,如果使用类似Log4j之类的框架那就大财小用了,所以自己写了一个日志工具类,实现了简单的信息打印在控制台及可以将信息输出到一个文件里。
工具亮点
- 使用简单,工具分为控制台打印和文件打印两块,全部使用静态方法实现。
- 工具的控制台打印自带跳转到打印位置的功能。
- 工具具有详细的解释
源代码
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* 日志打印工具
*
* @author cxy
*/
public class LogPrintUtils {
public static class LogFile {
/**
* 日志打印路径
*/
public static String logSavePath;
public static PrintStream printStream;
public static OutputStream outputStream;
static {
//初始化日志路径
logSavePath = Thread.currentThread().getContextClassLoader().getResource("").getPath();
setLogFilePath(logSavePath);
}
/**
* 设置日志文件路径
* @param path
*/
public static void setLogFilePath(String path){
setLogFilePath(path, null);
}
/**
* 设置日志文件路径
* @param path
* @param fileName
*/
public static void setLogFilePath(String path, String fileName) {
if (path != null || path.length() > 0) {
path = path.replaceAll("\\\\", "/");
File file = new File(path);
if (file.exists()) {
if (file.isFile()) {
logSavePath = path;
newPrintStream();
} else {
if (file.isDirectory()) {
Console.errMessage("注意:"+ file +" 这是一个隐藏文件路径");
}
String name = "logFile.log";
if (path.charAt(path.length() - 1) != '/') {
path += "/";
}
logSavePath = path + name;
if(fileName != null && fileName.length() != 0){
File file1 = new File(path + fileName);
try {
if(!file1.createNewFile()){
Console.errMessage("注意:"+ file1 +" 文件已存在,日志将写入文件末尾,如果文件有其他作用,请修改文件名");
}
logSavePath = path + fileName;
} catch (IOException e) {
Console.errMessage("注意:"+ file1 +" 文件创建不成功,文件名不合格,文件名采用工具默认");
}
}
newPrintStream();
}
} else {
Console.errMessage("注意:"+ file +" 文件路径不存在设置不成功,采用工具默认路径打印");
}
}
}
/**
* 更新打印流
*/
public static void newPrintStream() {
try {
/**
* 这里不关闭outputStream是因为printStream.close();通过刷新流然后关闭底层输出流
*/
if (printStream != null) {
printStream.close();
}
outputStream = new FileOutputStream(logSavePath, true);
printStream = new PrintStream(outputStream);
} catch (IOException e) {
e.printStackTrace();
new IOException("创建文件流失败");
}
}
/**
* 打印
*
* @param str
*/
public static void print(String str) {
writeString(printStream, getDateString() + str, false);
}
/**
* 打印
*
* @param str
*/
public static void println(String str) {
writeLnString(printStream, getDateString() + str);
}
/**
* 打印带打印位置信息
*
* @param str
*/
public static void printlnBandMessage(String str) {
str = "打印位置:" + getPrintString(getPrintPlaceMessage()) + " 打印信息:" + str;
writeLnString(printStream, getDateString() + str);
}
private static String getDateString() {
SimpleDateFormat formatter = new SimpleDateFormat("yyyy年MM月dd日HH:mm:ss:SSS");
return "时间:" + formatter.format(new Date()) + " ";
}
}
public static class Console {
public static PrintStream outPrintStream;
public static PrintStream errPrintStream;
static {
outPrintStream = new PrintStream(System.out);
errPrintStream = new PrintStream(System.err);
}
public static void out(String str) {
writeLnString(System.out, str);
}
public static void err(String str) {
writeLnString(System.err, str);
}
/**
* 打印调用打印位置信息不能跳转
*
* @param str
*/
public static void outMessage(String str) {
printBandPlaceMessage(getPrintPlaceMessage(), str, outPrintStream, false);
}
/**
* 打印调用打印位置信息并且可以点击控制台跳转
*
* @param str
*/
public static void outSkipMessage(String str) {
printBandPlaceMessage(getPrintPlaceMessage(), str, outPrintStream, true);
}
/**
* 错误打印调用打印位置信息不能跳转
*
* @param str
*/
public static void errMessage(String str) {
printBandPlaceMessage(getPrintPlaceMessage(), str, errPrintStream, false);
}
/**
* 错误打印调用打印位置信息并且可以点击控制台跳转
*
* @param str
*/
public static void errSkipMessage(String str) {
printBandPlaceMessage(getPrintPlaceMessage(), str, errPrintStream, true);
}
/**
* 打印调用打印位置信息
* @param element
* @param str
* @param outputStream
* @param flag true:点击控制台能实现跳转到打印位置
*/
public static void printBandPlaceMessage(StackTraceElement element, String str, OutputStream outputStream, boolean flag) {
str = (flag ? getSkipPrintString(element) : getPrintString(element)) + " 打印信息:" + str;
writeLnString(outputStream, str);
}
/**
* 打印调用打印位置信息
* @param element
* @param str
* @param printStream
* @param flag true:点击控制台能实现跳转到打印位置
*/
public static void printBandPlaceMessage(StackTraceElement element, String str, PrintStream printStream, boolean flag) {
str = (flag ? getSkipPrintString(element) : getPrintString(element)) + " 打印信息:" + str;
writeLnString(printStream, str);
}
}
/**
* 将数据通过流发送出去,
*
* @param outputStream
* @param str
* @param flag
*/
public static PrintStream writeString(OutputStream outputStream, String str, Boolean flag) {
PrintStream printStream = new PrintStream(outputStream);
return writeString(printStream, str, flag);
}
/**
* 将数据通过流发送出去,
*
* @param printStream
* @param str
* @param flag
*/
public static PrintStream writeString(PrintStream printStream, String str, Boolean flag) {
printStream.print(str);
printStream.flush();
if (flag == null || flag) {
printStream.close();
return null;
}
return printStream;
}
/**
* 将数据通过流发送出去尾部自动换行
*
* @param outputStream
* @param str
*/
public static void writeLnString(OutputStream outputStream, String str) {
writeString(outputStream, str + "\n", false);
}
/**
* 将数据通过流发送出去尾部自动换行
*
* @param printStream
* @param str
*/
public static void writeLnString(PrintStream printStream, String str) {
writeString(printStream, str + "\n", false);
}
public static List<StackTraceElement> getStackTraceElements() {
StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
List<StackTraceElement> elementList = new ArrayList<StackTraceElement>();
for (StackTraceElement element : stackTrace) {
elementList.add(element);
}
return elementList;
}
/**
* 获取指定的堆栈层数
*
* @param i
* @return
*/
public static StackTraceElement getIndexStackTraceElement(int i) {
List<StackTraceElement> stackTraceElements = getStackTraceElements();
if (i > stackTraceElements.size()) {
i = stackTraceElements.size() - 1;
}
return stackTraceElements.get(i);
}
/**
* 在本类中获取StackTraceElement,由于可能存在嵌套调用所以这里只能为单层调用
*
* @return
*/
private static StackTraceElement getPrintPlaceMessage() {
return getIndexStackTraceElement(6);
}
/**
* 供外部调用获取StackTraceElement
*
* @return
*/
public static StackTraceElement getStackTraceElement() {
return getIndexStackTraceElement(4);
}
/**
* 拼接字符串
*
* @param strings
* @return
*/
public static String stringConnect(String... strings) {
StringBuffer buffer = new StringBuffer();
for (String s : strings) {
buffer.append(s);
}
return buffer.toString();
}
/**
* 返回可跳转的字符串
*
* @param classPackage 类包
* @param className 类名
* @param methodName 方法
* @param customString 自定义跳转显示字符串
* @param lineNumber 行号
* @return
*/
public static String getSkipPrintString(String classPackage, String className, String methodName, String customString, int lineNumber) {
String str = null;
if (methodName == null || methodName.length() == 0) {
methodName = "java";
}
if (customString == null || customString.length() == 0) {
customString = "To";
}
if (className == null) {
className = "";
}
str = classPackage + "." + className + "." + methodName + "(" + className + ".java " + customString + ":" + lineNumber + ")";
return str;
}
/**
* 返回可跳转的字符串
*
* @param element
* @return
*/
public static String getSkipPrintString(StackTraceElement element) {
String[] strings = splitClassPackageString(element.getClassName());
return getSkipPrintString(strings[0], strings[1], element.getMethodName(), null, element.getLineNumber());
}
/**
* 拆分包和类名
*
* @param classPackageStr 类包字符串
* @return
*/
public static String[] splitClassPackageString(String classPackageStr) {
String[] strings = {"", ""};
int i = classPackageStr.lastIndexOf(".");
strings[0] = classPackageStr.substring(0, i);
strings[1] = classPackageStr.substring(i + 1);
return strings;
}
/**
* 返回普通信息
*
* @param element
* @return
*/
public static String getPrintString(StackTraceElement element) {
return element.getClassName() + "." + element.getMethodName() + ":" + element.getLineNumber();
}
}
测试
/**
* @author cxy
*/
public class Test {
public static void main(String[] args) {
/**
* 打印调用打印位置信息不能跳转
*/
LogPrintUtils.Console.outMessage("打印");
/**
* 打印调用打印位置信息并且可以点击控制台跳转
*/
LogPrintUtils.Console.outSkipMessage("打印");
/**
* 错误打印调用打印位置信息不能跳转
*/
LogPrintUtils.Console.errMessage("打印");
/**
* 错误打印调用打印位置信息并且可以点击控制台跳转
*/
LogPrintUtils.Console.errSkipMessage("打印");
/**
* 在文件打印之前可以先设置文件路径和文件名,使用setLogFilePath方法,
* 注意:默认的换行为“\n”,文件用windows记事本打开无法换行,修改源代码把
* “\n”换位“\r\n”
* 默认文件路径为类路径,默认文件名为logFile.log
* 如:只设置文件路径
* LogPrintUtils.LogFile.setLogFilePath("C:\\Users\\user\\Desktop");
* 如:文件名和路径同时设置
* LogPrintUtils.LogFile.setLogFilePath("C:\\Users\\user\\Desktop", "log.txt");
*/
LogPrintUtils.LogFile.setLogFilePath("C:\\Users\\user\\Desktop\\", "log.txt");
/**
* 向文件写入普通信息(不带换行)
*/
LogPrintUtils.LogFile.print("测试");
/**
* 向文件写入普通信息(带换行)
*/
LogPrintUtils.LogFile.println("测试");
/**
* 向文件写入带打印位置信息(带换行)
*/
LogPrintUtils.LogFile.printlnBandMessage("测试1");
}
}