能否将system.in、system.out和system.err重新映射到Java线程? 我有一些旧的C++代码,它使用STDIO进行输入和输出。代码还通过分叉生成新的进程。它将stdio重新映射到每个新进程,以便每个会话获得各自的数据

能否将system.in、system.out和system.err重新映射到Java线程? 我有一些旧的C++代码,它使用STDIO进行输入和输出。代码还通过分叉生成新的进程。它将stdio重新映射到每个新进程,以便每个会话获得各自的数据,java,multithreading,fork,stdio,Java,Multithreading,Fork,Stdio,我正在考虑使用Java中的线程来创建子进程。但是,当我发现如何在创建时将System.in、System.out和System.err重新映射到子线程时,我就陷入了困境 如果可能的话,有人能给我指出正确的方向吗?简单的答案是不要直接访问System.out/in/err来编写代码。而是将一个InputStream和两个OutputStream传递给对象的构造函数。然后,对象直接与这些对象一起工作,而不依赖于它们实际映射到的对象。要访问print()和println(),您需要将OutputStr

我正在考虑使用Java中的线程来创建子进程。但是,当我发现如何在创建时将
System.in
System.out
System.err
重新映射到子线程时,我就陷入了困境


如果可能的话,有人能给我指出正确的方向吗?

简单的答案是不要直接访问System.out/in/err来编写代码。而是将一个
InputStream
和两个
OutputStream
传递给对象的构造函数。然后,对象直接与这些对象一起工作,而不依赖于它们实际映射到的对象。要访问
print()
println()
,您需要将
OutputStream
传递给
PrintStream
的构造函数


然后根据您实际想要做的事情,您可以使用System.out或某个
FileOutputStream
调用构造函数生成线程与生成进程不同。在java(和c++中)中生成线程时,它与生成程序共享相同的内存空间(即,它们共享相同的sdio流)。如果您想在java中生成一个新进程,您可以使用Runtime.exec(),然后您必须手动将io导入新进程,java不支持跨进程边界共享io流。

java没有fork(),但它有ProcessBuilder和Runtime.exec()来启动新进程(进程类的对象)。您可以将其视为fork()/exec()对,但不能在两者之间执行诸如dup2()之类的操作。这意味着您不能重定向子进程的stdio,但可以显式地将某些内容写入其stdin,并使用相应的进程方法,或者确切地说,使用getInputStream()/getOutputStream()/getErrorStream()返回的输入/输出流的相应方法,从其stdout和stderr读取进程类的方法。如果希望使用进程而不是线程,这可能是有效的解决方法


如果您想使用线程,那么它们都共享相同的stdio。您可以重定向它,但它将毫无意义,因为重定向将影响所有线程。您可以对使用自定义InputStream/OutputStream实现的线程使用某种IPC模拟,或者您可能希望查看PipedInputStream/PipedOutputStream对。它们实际上可以用来设置类似IPC管道的东西,可能与BufferedInputStream/BufferedOutputStream结合使用,以避免过度阻塞。

我建议使用单独的进程,或者为每个线程显式分配一个PrintStream


但是,即使每个线程看到System.out的同一对象,也可以将对System.out的写入转发到每个线程的不同位置。在启动代码中,您可以使用自定义的PrintStream调用System.setOut(PrintStream)。此PrintStream将覆盖所有打印和写入方法。在这些方法中,它将使用InheritableThreadLocal查找线程的PrintStream,并将方法调用转发给它。

线程与进程不同,不能使用它们“创建子进程”。它们共享相同的数据,包括stdio内容。如果从一个线程重新映射,它将影响所有线程。我的意思是java似乎没有像fork()这样的方法,所以我想知道是否可以使用线程来执行任务,而不是进程。也许.exec()是一种方法,但是,我可以用同样的方法重新映射stdio吗?对于那些处于相同情况的人,他们可以从这个答案中获得灵感:。生成过程似乎是一种方法。只是担心内存使用,这就是为什么我仍然渴望找到一个线程解决方案,我想这取决于开销。谢谢你。@andicrook,是的,Java有时会占用内存。我不会求助于使用进程,除非我想要一个真正健壮的应用程序,即使其中一个子进程崩溃也可以继续运行。线程有时调试起来会很痛苦,但一旦掌握了窍门,它们通常也会更容易使用和更高效,尤其是在内存方面。