将Throwable.getStackTrace()的结果转换为描述堆栈跟踪的字符串最简单的方法是什么?
当前回答
我不久前写了一些方法,所以我想为什么不花我的两分钱。
/** @param stackTraceElements The elements to convert
* @return The resulting string */
public static final String stackTraceElementsToStr(StackTraceElement[] stackTraceElements) {
return stackTraceElementsToStr(stackTraceElements, "\n");
}
/** @param stackTraceElements The elements to convert
* @param lineSeparator The line separator to use
* @return The resulting string */
public static final String stackTraceElementsToStr(StackTraceElement[] stackTraceElements, String lineSeparator) {
return stackTraceElementsToStr(stackTraceElements, lineSeparator, "");
}
/** @param stackTraceElements The elements to convert
* @param lineSeparator The line separator to use
* @param padding The string to be used at the start of each line
* @return The resulting string */
public static final String stackTraceElementsToStr(StackTraceElement[] stackTraceElements, String lineSeparator, String padding) {
String str = "";
if(stackTraceElements != null) {
for(StackTraceElement stackTrace : stackTraceElements) {
str += padding + (!stackTrace.toString().startsWith("Caused By") ? "\tat " : "") + stackTrace.toString() + lineSeparator;
}
}
return str;
}
/** @param stackTraceElements The elements to convert
* @return The resulting string */
public static final String stackTraceCausedByElementsOnlyToStr(StackTraceElement[] stackTraceElements) {
return stackTraceCausedByElementsOnlyToStr(stackTraceElements, "\n");
}
/** @param stackTraceElements The elements to convert
* @param lineSeparator The line separator to use
* @return The resulting string */
public static final String stackTraceCausedByElementsOnlyToStr(StackTraceElement[] stackTraceElements, String lineSeparator) {
return stackTraceCausedByElementsOnlyToStr(stackTraceElements, lineSeparator, "");
}
/** @param stackTraceElements The elements to convert
* @param lineSeparator The line separator to use
* @param padding The string to be used at the start of each line
* @return The resulting string */
public static final String stackTraceCausedByElementsOnlyToStr(StackTraceElement[] stackTraceElements, String lineSeparator, String padding) {
String str = "";
if(stackTraceElements != null) {
for(StackTraceElement stackTrace : stackTraceElements) {
str += (!stackTrace.toString().startsWith("Caused By") ? "" : padding + stackTrace.toString() + lineSeparator);
}
}
return str;
}
/** @param e The {@link Throwable} to convert
* @return The resulting String */
public static final String throwableToStrNoStackTraces(Throwable e) {
return throwableToStrNoStackTraces(e, "\n");
}
/** @param e The {@link Throwable} to convert
* @param lineSeparator The line separator to use
* @return The resulting String */
public static final String throwableToStrNoStackTraces(Throwable e, String lineSeparator) {
return throwableToStrNoStackTraces(e, lineSeparator, "");
}
/** @param e The {@link Throwable} to convert
* @param lineSeparator The line separator to use
* @param padding The string to be used at the start of each line
* @return The resulting String */
public static final String throwableToStrNoStackTraces(Throwable e, String lineSeparator, String padding) {
if(e == null) {
return "null";
}
String str = e.getClass().getName() + ": ";
if((e.getMessage() != null) && !e.getMessage().isEmpty()) {
str += e.getMessage() + lineSeparator;
} else {
str += lineSeparator;
}
str += padding + stackTraceCausedByElementsOnlyToStr(e.getStackTrace(), lineSeparator, padding);
for(Throwable suppressed : e.getSuppressed()) {
str += padding + throwableToStrNoStackTraces(suppressed, lineSeparator, padding + "\t");
}
Throwable cause = e.getCause();
while(cause != null) {
str += padding + "Caused by:" + lineSeparator + throwableToStrNoStackTraces(e.getCause(), lineSeparator, padding);
cause = cause.getCause();
}
return str;
}
/** @param e The {@link Throwable} to convert
* @return The resulting String */
public static final String throwableToStr(Throwable e) {
return throwableToStr(e, "\n");
}
/** @param e The {@link Throwable} to convert
* @param lineSeparator The line separator to use
* @return The resulting String */
public static final String throwableToStr(Throwable e, String lineSeparator) {
return throwableToStr(e, lineSeparator, "");
}
/** @param e The {@link Throwable} to convert
* @param lineSeparator The line separator to use
* @param padding The string to be used at the start of each line
* @return The resulting String */
public static final String throwableToStr(Throwable e, String lineSeparator, String padding) {
if(e == null) {
return "null";
}
String str = padding + e.getClass().getName() + ": ";
if((e.getMessage() != null) && !e.getMessage().isEmpty()) {
str += e.getMessage() + lineSeparator;
} else {
str += lineSeparator;
}
str += padding + stackTraceElementsToStr(e.getStackTrace(), lineSeparator, padding);
for(Throwable suppressed : e.getSuppressed()) {
str += padding + "Suppressed: " + throwableToStr(suppressed, lineSeparator, padding + "\t");
}
Throwable cause = e.getCause();
while(cause != null) {
str += padding + "Caused by:" + lineSeparator + throwableToStr(e.getCause(), lineSeparator, padding);
cause = cause.getCause();
}
return str;
}
例子:
try(InputStream in = new FileInputStream(file)) {
...
} catch(IOException e) {
String exceptionToString = throwableToStr(e);
someLoggingUtility.println(exceptionToString);
...
}
打印:
java.io.FileNotFoundException: C:\test.txt (The system cannot find the file specified)
at java.io.FileInputStream.open0(Native Method)
at java.io.FileInputStream.open(Unknown Source)
at java.io.FileInputStream.<init>(Unknown Source)
at com.gmail.br45entei.Example.main(Example.java:32)
其他回答
可以使用以下方法将异常堆栈跟踪转换为字符串。该类在Apache commons-lang中可用,这是许多流行开源中最常见的依赖库
org.apache.commons.lang.exception.ExceptionUtils.getStackTrace(可丢弃)
没有java.io.*,它可以这样做。
String trace = e.toString() + "\n";
for (StackTraceElement e1 : e.getStackTrace()) {
trace += "\t at " + e1.toString() + "\n";
}
然后跟踪变量保存堆栈跟踪。输出也包含初始原因,输出与printStackTrace()相同
例如,printStackTrace()产生:
java.io.FileNotFoundException: / (Is a directory)
at java.io.FileOutputStream.open0(Native Method)
at java.io.FileOutputStream.open(FileOutputStream.java:270)
at java.io.FileOutputStream.<init>(FileOutputStream.java:213)
at java.io.FileOutputStream.<init>(FileOutputStream.java:101)
at Test.main(Test.java:9)
当打印到stdout时,跟踪字符串保持
java.io.FileNotFoundException: / (Is a directory)
at java.io.FileOutputStream.open0(Native Method)
at java.io.FileOutputStream.open(FileOutputStream.java:270)
at java.io.FileOutputStream.<init>(FileOutputStream.java:213)
at java.io.FileOutputStream.<init>(FileOutputStream.java:101)
at Test.main(Test.java:9)
如果你是为Android开发的,一个更简单的方法是使用这个:
import android.util.Log;
String stackTrace = Log.getStackTraceString(exception);
格式与getStacktrace相同,例如。
09-24 16:09:07.042:I/System.out(4844):java.lang.NullPointerException09-24 16:09:07.042:I/System.out(4844):在com.temp.ttscancel.MainActivity.onCreate(MainActivity.java:43)09-24 16:09:07.042:I/System.out(4844):在android.app.Activity.performCreate(Activity.java:5248)09-24 16:09:07.043:I/System.out(4844):在android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1110)09-24 16:09:07.043:I/System.out(4844):在android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2162)09-24 16:09:07.043:I/System.out(4844):在android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2257)09-24 16:09:07.043:I/System.out(4844):在android.app.ActivityThread.access$800(ActivityThread.java:139)09-24 16:09:07.043:I/System.out(4844):在android.app.ActivityThread$H.handleMessage(ActivityThread.java:1210)09-24 16:09:07.043:I/System.out(4844):在android.os.Handler.dispatchMessage(Handler.java:102)09-24 16:09:07.043:I/System.out(4844):在android.os.Looper.lop(Looper.java:136)09-24 16:09:07.044:I/System.out(4844):在android.app.ActivityThread.main(ActivityThread.java:5097)09-24 16:09:07.044:I/System.out(4844):在java.lang.reflect.Method.invokeNative(本机方法)09-24 16:09:07.044:I/System.out(4844):在java.lang.reflect.Method.invoke(Method.java:515)09-24 16:09:07.044:I/System.out(4844):在com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)09-24 16:09:07.044:I/System.out(4844):在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
将堆栈跟踪打印到PrintStream,然后将其转换为字符串:
// ...
catch (Exception e)
{
ByteArrayOutputStream out = new ByteArrayOutputStream();
e.printStackTrace(new PrintStream(out));
String str = new String(out.toByteArray());
System.out.println(str);
}
解决方案是将数组的stackTrace转换为字符串数据类型。请参见以下示例:
import java.util.Arrays;
try{
}catch(Exception ex){
String stack = Arrays.toString(ex.getStackTrace());
System.out.println("stack "+ stack);
}
推荐文章
- 在Java中使用UUID的最重要位的碰撞可能性
- 转换列表的最佳方法:map还是foreach?
- 如何分割逗号分隔的字符串?
- Java字符串—查看字符串是否只包含数字而不包含字母
- Mockito.any()传递带有泛型的接口
- 在IntelliJ 10.5中运行测试时,出现“NoSuchMethodError: org.hamcrest. matcher . descripbemismatch”
- 使用String.split()和多个分隔符
- Java数组有最大大小吗?
- 在Android中将字符串转换为Uri
- 从JSON生成Java类?
- 为什么java.util.Set没有get(int index)?
- Swing和AWT的区别是什么?
- 为什么Java流是一次性的?
- 四舍五入BigDecimal *总是*有两位小数点后
- 设计模式:工厂vs工厂方法vs抽象工厂