如何使用java在外部控制台应用程序中多次写入?

时间:2015-01-24 12:49:01

标签: java process outputstream

我需要与外部c ++控制台程序对话(读取输出和写入输入)。我从应用程序读取一个线程(并且它工作),但是当它需要输入时,它只在第一次工作,然后流可能保持为空,并且它不接收第二个输入(并且外部程序关闭)。

我正在使用的应用程序是一个简单的.exe在c ++中写道:

  1. print“插入第一个输入”
  2. scan input1
  3. print input1
  4. print“插入第二个输入”
  5. scan input2
  6. print input2
  7. 主要课程:

        import java.io.*;
        import java.util.Scanner;
        public class ExampleCom {
    
        public static Communication com = new Communication();
    
        public static void main(String[] args) 
        {
            Scanner in = new Scanner(System.in);
            String s;
    
            com.read();
            while(true)
            {
                s = in.nextLine();
                com.write(s);
            }
        }
    

    沟通课程:

        public class Communication
        {
            Process p;
            OutputStream writer;
            public InputStream reader = null;
            Read r; //Class that with a loop read all exe input
    
            Communication()
            {   
                try{
                    p = Runtime.getRuntime ().exec ("C:\\esempio.exe");
                    writer = p.getOutputStream();
                    reader = p.getInputStream();
                }catch(Exception e){}
            }
    
            public void read()
            {
                r = new Read();
                Thread threadRead = new Thread(r);
                threadRead.start();
            }
    
            public void write(String s)
            {
                try{
                    writer.write(s.getBytes());
                    writer.flush();
                    writer.close();
                }catch(Exception e){}
            }
        }
    

    当外部应用程序需要时,我如何发送我的字符串(如“writer.write('hello')”)?

2 个答案:

答案 0 :(得分:0)

问题是,在write()方法中,您有

            writer.close();

这意味着在第一次调用它之后,您正在关闭C ++的输入流。就它而言,它会在您第一次输入后看到“文件结束”标记。

您应该做的是将close()放在一个单独的方法中,并且只有在您完成该过程后才调用该方法。

现在,由于您的目标程序需要文本输入,并且只有在输入结束时才会解释输入(根据您在评论中对问题的回答),您应该提供该行尾它

我认为更好的方法是使用PrintWriter作为输出流,而不是使用原始字节写入,并且使用System.out.println()时自然使用。它还可以将您保存在flush()部分。

如果在close()之前发现你的程序没有读取输入,那么你的解释是错误的。它不是在等待 - 它会在您拨打flush()后立即发送。但是C ++会等待文件结束或行尾,并且因为你没有给它一个行尾,只有close(),它会发送文件结尾,使它接受输入。但是,您无法再发送任何其他数据。

首先,解决方案是将writer定义为PrintWriter。而不是

OutputStream writer;

使用

PrintWriter writer;

而不是

            writer = p.getOutputStream();

使用

            writer = new PrintWriter(p.getOutputStream(), true);

true只要您使用println()命令,就会自动刷新。

现在,你的写法应该是:

    public void write(String s)
    {
        writer.println(s);
    }

请注意,PrintWriter不会产生异常,因此如果您关心错误,则必须使用checkError()进行检查。

当然,正如我之前提到的那样,将close()放在一个单独的方法中。

答案 1 :(得分:0)

因为write()方法可能抛出IOException,所以建议在finally块中调用close()方法。将writer.close()方法放在try子句之外:

finally {
if(writer != null) {
    writer.close();
}