Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在System.out.close()之后重新创建System.out以在控制台中再次打印_Java_Console_Jvm_System.out - Fatal编程技术网

Java 在System.out.close()之后重新创建System.out以在控制台中再次打印

Java 在System.out.close()之后重新创建System.out以在控制台中再次打印,java,console,jvm,system.out,Java,Console,Jvm,System.out,我有一个桌面应用程序,当冻结几分钟时,有一个线程监视冻结,它开始将所有线程的堆栈跟踪转储到临时文件中(这是在本机调用中完成的,以便可以调用JVM\u DumpAllStacks)。然后,在本机调用之后,临时文件被读取为字符串,并用于登录应用程序自己的日志框架 问题是,在所有这些过程之后,我无法将System.out恢复到控制台流 下面的代码对此进行了更好的解释 public String getAllStackTraces() { System.out.println("This will b

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

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

下面的代码对此进行了更好的解释

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");
} 
现在,有没有办法让控制台的输出流再次开始在控制台中打印


注意:应用程序正在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);
作为本机代码的替代方案,您可以调用。返回的对象包含关于持有的锁和线程正在等待的锁的信息

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();
    }
}

你不能存储existion System.out,设置新的,然后重新分配旧的吗?为什么不使用任何日志库?@Jan我不能再次使用控制台的相同
系统。out
,因为它已关闭,我应该以某种方式再次获得控制台的新
PrintStream
,通过
System.setOut
进行设置,因此无论我在哪里
System.out.println(“某物”)
它将以console@Everv0id你能给我举个例子吗?在这个例子中,某个日志库转储了所有线程的堆栈跟踪。@SenthilkumarAnnadurai只是不关闭系统。out这不起作用,并且本机代码仍然在控制台中打印,而不是
setToNew
本机代码??为什么不迭代Thread.getAllStacKTraces()呢?这是一个好主意,但在死锁情况下,某些信息会丢失,例如特定线程正在等待的对象的信息和它已获得锁的对象的信息。虽然可以花费时间来识别事物,但当堆栈很大且堆栈中的类和方法名称重复时(如果死锁涉及两个以上的线程),这会使问题变得复杂。代码在GUI冻结上执行,其中死锁的可能性很高。”JVM_DumpAllStacks'实际上执行线程转储并提供更好的信息。请参阅我对使用ThreadMXBean在没有本机代码的情况下包含锁信息所做的更改。“这不起作用,本机代码仍然在控制台中打印,而不是在setToNew中打印”,您也不希望这样做,只有本机代码调用回Java以使用
System.out
,它将重定向到您设置的
System.out
。改变这个领域,只要改变这个领域,没有其他神奇的事情发生。如果您有直接打印到控制台或任何其他文件描述符的本机代码,则不受影响。