gpt4 book ai didi

java - 在 System.out.close() 之后重新创建 System.out 以在 CONSOLE 中再次打印

转载 作者:行者123 更新时间:2023-11-30 08:43:34 26 4
gpt4 key购买 nike

我有一个桌面应用程序,当有几分钟的卡住时,有一个线程监视卡住并开始转储所有线程的堆栈跟踪(这是在 native 调用中完成的,以便 JVM_DumpAllStacks 可以被调用)到临时文件中。然后临时文件在 native 调用后被读取为字符串,用于登录应用程序自己的日志框架。

问题是,在所有这些过程之后,我无法将 System.out 恢复到 CONSOLE 流。

这在下面的代码中有更好的解释。

public String getAllStackTraces() {

System.out.println("This will be printed in CONSOLE");

// This is NECESSARY for the jvm to dump stack traces in specific file which we are going to set in System.setOut call.
System.out.close();

File tempFile = File.createTempFile("threadDump",null,new File(System.getProperty("user.home")));
System.setOut(new PrintStream(new BufferedOutputStream(new FileOuptputStream(tempFile))));

//This native call dumps stack traces all threads to tempFile
callNativeMethodToDumpAllThreadStackTraces();

String stackTraces = readFileAsString(tempFile);
//close the tempFile PrintStream so as the next PrintStream object to set as 'out' and to take effect in the native side as well
System.out.close();

//Now I want to start printing in the CONSOLE again. How to do it again ?
//The below line does not work as FileDescriptor.out becomes invalid (i.e FileDescriptor.out.fd, handle = -1) after we do System.out.close() where out is PrintStream of console.
//System.setOut(new PrintStream(new BufferedOutputStream(new FileOuptputStream(FileDescriptor.out))));

PrintStream standardConsoleOutputStream = magicallyGetTheOutputStream() // How ???????????
System.setOut(standardConsoleOutputStream);
System.out.println("This will be printed in CONSOLE !ONLY! if we are able to get the new PrintStream of Console again magically");
}

现在,有没有办法让控制台的 magicallyGetTheOutputStream 再次开始在控制台打印?

注意:该应用程序在 java 5 和 6 中运行。

最佳答案

考虑这段代码如何在不关闭的情况下存储原始 System.out,以便稍后将其恢复到完整状态:

    //Store, don't close
PrintStream storeForLater = System.out;
//Reassign
System.out(setToNew);
...
//Close reassigned
setToNew.close();
//Reset to old
System.setOut(storeForLater);

作为 native 代码的替代方案,您可以调用 ThreadMXBean .返回的 ThreadInfo对象包含有关持有的锁和线程正在等待的锁的信息。

public static void dumpThreads(PrintStream out) {
ThreadInfo[] threads = ManagementFactory.getThreadMXBean()
.dumpAllThreads(true, true);
for(final ThreadInfo info : threads) {
out.println("Thread: " + info.getThreadId()
+ "/" + info.getThreadName()
+ " in State " + info.getThreadState().name());
if(info.getLockName() != null) {
out.println("- Waiting on lock: " + info.getLockInfo().toString()
+ " held by " + info.getLockOwnerId()+"/"+info.getLockOwnerName());
}
for(MonitorInfo mi : info.getLockedMonitors()) {
out.println(" Holds a lock on a " + mi.getClassName() +
" from " + mi.getLockedStackFrame().getClassName()+"."+mi.getLockedStackFrame().getMethodName()
+ ": " + mi.getLockedStackFrame().getLineNumber());
}
for(StackTraceElement elm : info.getStackTrace()) {
out.println(" at " + elm.getClassName() + "."
+ elm.getMethodName() + ":"+elm.getLineNumber());
}
out.println();
}
}

关于java - 在 System.out.close() 之后重新创建 System.out 以在 CONSOLE 中再次打印,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34172384/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com