简单的 Java 进程输入/输出失败

Posted

技术标签:

【中文标题】简单的 Java 进程输入/输出失败【英文标题】:Simple Java Process Input/Output failing 【发布时间】:2014-11-29 09:49:02 【问题描述】:

我已经查看了许多关于 Java 中衍生进程的输入/输出的问题,但我仍然无法弄清楚我的程序出了什么问题。它真的很短很简单,但它不起作用。我正在使用 Runtime 对象的 exec() 方法来创建新进程(我知道 ProcessBuilder 可能更好,但这是一个简单的分配,我真的不必担心生成进程的 stderr) .

我自己从 IDE/命令行运行“处理器”类。 Memory.java 在同一目录中。

public class Memory 

    public static void main(String[] args)
    
        System.out.println("Memory works!");
    

还有其他程序:

import java.io.IOException;
import java.io.InputStream;

public class Processor 

    public static void main(String[] args)
    
        Runtime rt = Runtime.getRuntime();
        Process proc = null;

        try 
            proc = rt.exec("java Memory");  //execute Memory.java which is in same directory
         catch (IOException e) 
            // TODO Auto-generated catch block
            e.printStackTrace();
            System.exit(2); //exit code 2 means that process creation failed.
        

        //stream to get output from memory
        InputStream fromProcess = proc.getInputStream();

        int x;

        try 
            while((x = fromProcess.read()) != -1)
                System.out.print((char)x);
         catch (IOException e) 
            // TODO Auto-generated catch block
            e.printStackTrace();
        
    

没有输出,程序永远不会终止。现在这可能是因为扫描器内存中的 while 循环,但至少应该有一些输出吧?

【问题讨论】:

“我真的不必担心衍生进程的标准错误”嗯...看看它:它肯定会告诉你出错了;-) 我建议您使用几个调试步骤来了解正在发生的事情。首先,请注意 stderr,因为它可能会指出您的问题。其次,尝试运行一些其他命令,您确定它将作为 ls 或 dir 命令输出到标准输出,具体取决于您正在工作的操作系统,如果您看到输出,这也可以告诉您正在使用哪个当前目录,这将是有帮助的只是为了确保我们处于正确的环境中。最后我只是为了检查,处理器类执行的当前目录中是否有编译好的 memory.class 文件? 我已经回滚了您的大量编辑...因为它们使当前的答案毫无用处。如果您的代码仍然存在问题,并且列出的其他建议(例如添加调试步骤),请提出一个单独的问题以缩小您遇到的新问题,并包括相关输出 【参考方案1】:

您在这里遇到的问题几乎可以肯定是“java Memory”命令失败了。

当您运行一个进程时,Java 会创建三个输出,即退出代码、STDOUT 和 STDERR。运行外部进程的好程序会检查所有三个。

您只是在检查 STDOUT。

如果您在构建 proc 后更改代码,则为:

    //stream to get output from memory
    InputStream fromProcess = proc.getInputStream();
    InputStream fromError = proc.getErrorStream();

    int x;

    try 
        while((x = fromProcess.read()) != -1)
            System.out.print((char)x);
     catch (IOException e) 
        // TODO Auto-generated catch block
        e.printStackTrace();
    
    try 
        while((x = fromError.read()) != -1)
            System.err.print((char)x);
     catch (IOException e) 
        // TODO Auto-generated catch block
        e.printStackTrace();
    

    int exit = proc.exitValue();
    System.out.println("Exited with code " + exit);

您将更好地了解问题所在。

管理这三个输出很难做到,许多系统实现了一个单独的线程来控制 STDERR 和 STDOUT 流。但是,您如何解决它超出了此问题的范围。

【讨论】:

我已经编辑了程序,现在处理器将数据发送到内存的标准输入,内存将其打印到标准输出(发送到处理器的 fromStream)。但什么也没有发生。非常感谢您的再次帮助,谢谢!【参考方案2】:

我试过你写的代码,它运行得很好......

您是想从命令行还是从 IDE 中运行它?我尝试从 Eclipse 中运行它并收到一个 IO 错误。它没有注册 Memory.class 所在的位置。

我退出到文件系统并导航到 Memory.class 和 Processor.class 所在的位置。从该目录中执行工作正常。

【讨论】:

是的,这就是错误。我从 Eclipse 运行它并没有检查错误流。但是现在当我尝试来回发送数据时,我遇到了问题。请参阅已编辑的问题。再次感谢! 你试过从命令行运行它吗?就像我说的,它运行得很好,正如我所写的那样。

以上是关于简单的 Java 进程输入/输出失败的主要内容,如果未能解决你的问题,请参考以下文章

具有并发输入/输出流的 Java 进程

Java示例:如何执行进程并读取输出

Java 输入/输出——Java虚拟机读写其它进程的数据

Windows 中 Java 进程缺少命令行输出

使用标准输入和标准输出在 2 个进程之间进行通信

java虚拟机读写其他进程的数据