我需要与外部c ++控制台程序对话(读取输出和写入输入)。我从应用程序读取一个线程(并且它工作),但是当它需要输入时,它只在第一次工作,然后流可能保持为空,并且它不接收第二个输入(并且外部程序关闭)。
我正在使用的应用程序是一个简单的.exe在c ++中写道:
主要课程:
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')”)?
答案 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();
}