Java ROOT 包装器。 OutputStreamReader 正在阻塞
Java wrapper for ROOT. OutputStreamReader is blocking
TLDR;有没有一种友好的方式让 Java 从 ROOT stdout 读取?反之亦然?
我有一个启动 ROOT 进程的 Java 函数。 Java 和 ROOT 然后通过标准输入和标准输出进行通信。好吧,这就是计划。出于某种原因,我无法通过 Java 进程访问 cin
(ROOT) 输出的任何信息。
我确定我在这里偶然发现了几个同时存在的陷阱,很抱歉这个问题太长了,包含的代码尽可能简单
根代码:
void test_io(){
while (true){
string in_str;
cout << "ROOT:: loop iteration";
//cout.flush(); flushing has no effect
cin >> in_str;
cout << "ROOT:: received string " << in_str;
}
}
我运行此代码使用以下命令:
root -b -q external/test_io.C
输出如下:
------------------------------------------------------------
| Welcome to ROOT 6.02/05 http://root.cern.ch |
| (c) 1995-2014, The ROOT Team |
| Built for linuxx8664gcc |
| From tag v6-02-05, 9 February 2015 |
| Try '.help', '.demo', '.license', '.credits', '.quit'/'.q' |
------------------------------------------------------------
root [0]
Processing external/test_io.C...
ROOT:: loop iteration
当我用键盘输入一些文本时,它会以明显的方式工作。
下面是相关的Java代码:
public void start() throws IOException{
/*
Start the process. create buffered reader and writer
*/
System.out.println("Java:: Starting Process...");
oProcess = new ProcessBuilder("root","-b","-q","external/test_io.C").start();
InputStream oIs = oProcess.getInputStream();
InputStreamReader oIsReader = new InputStreamReader(oIs);
oBr = new BufferedReader(oIsReader);
OutputStream oOs = oProcess.getOutputStream();
OutputStreamWriter oOsWriter = new OutputStreamWriter(oOs);
oBw = new BufferedWriter(oOsWriter);
}
public void communicate()throws IOException{
//sends stuff to the process and reads the results...
read_stuff();
write_stuff("message from java. blah blah blah");
read_stuff();
}
private void write_stuff(String sMessage)throws IOException{
System.out.println("Java:: write stuff: "+sMessage);
oBw.write(sMessage);
oBw.write("\n");
oBw.flush();
}
private void read_stuff()throws IOException{
/*
reads stuff from the external process. returns the last line recieved
*/
System.out.println("Java:: read_stuff...");
String sLine;
//wait for it to be ready...
long end=System.currentTimeMillis()+2000;
while ((System.currentTimeMillis() < end)){
if (oBr.ready())
break;
}
if (!oBr.ready()){
System.out.println("Java:: NOT READY :/");
return;
}
System.out.println("Java:: READY!!!");
while ((sLine = oBr.readLine()) != null) {
System.out.println("Java:: ...got line: " + sLine);
}
return;
}
调用 start
然后 communicate
产生以下输出:
Java:: Starting Process...
Java:: read_stuff...
Java:: READY!!!
Java:: ...got line: ------------------------------------------------------------
Java:: ...got line: | Welcome to ROOT 6.02/05 http://root.cern.ch |
Java:: ...got line: | (c) 1995-2014, The ROOT Team |
Java:: ...got line: | Built for linuxx8664gcc |
Java:: ...got line: | From tag v6-02-05, 9 February 2015 |
Java:: ...got line: | Try '.help', '.demo', '.license', '.credits', '.quit'/'.q' |
Java:: ...got line: ------------------------------------------------------------
Java:: ...got line:
Java:: ...got line:
Java:: ...got line: Processing external/test_io.C...
然后它阻塞了。 Java 甚至没有收到行 'ROOT:: loop iteration'.
如有任何帮助或指导,我们将不胜感激。我所有的谷歌搜索和实验都一无所获。
编辑
将 cout
语句更改为:cout << "stuff" << endl;
让事情变得更好一些。我的 java 程序输出现在看起来像:
Java:: Starting Process...
Java:: read_stuff...
Java:: READY!!!
Java:: ...got line: ------------------------------------------------------------
Java:: ...got line: | Welcome to ROOT 6.02/05 http://root.cern.ch |
Java:: ...got line: | (c) 1995-2014, The ROOT Team |
Java:: ...got line: | Built for linuxx8664gcc |
Java:: ...got line: | From tag v6-02-05, 9 February 2015 |
Java:: ...got line: | Try '.help', '.demo', '.license', '.credits', '.quit'/'.q' |
Java:: ...got line: ------------------------------------------------------------
Java:: ...got line:
Java:: ...got line:
Java:: ...got line: Processing external/test_io.C...
Java:: ...got line: ROOT:: loop iteration
然后阻塞。
从 ROOT 代码中删除行 cin >> in_str;
会导致 Java 生成以下无限内容:
Java:: ...got line: ROOT:: loop iteration
Java:: ...got line: ROOT:: recieved string
Java:: ...got line: ROOT:: loop iteration
...etc
所以现在的问题是cin
...
C++ 输出语句没有换行符,不会刷新行。
cout << "ROOT:: loop iteration" << endl;
cin >> in_str;
cout << "ROOT:: received string " << in_str << endl;
另一个问题是 cin 从不 "sees" 从 Java 程序发送的行。你从不执行
System.out.println("Java:: write stuff: "+sMessage);
等等
cin >> in_str;
块。 Java 程序块在
while ((sLine = oBr.readLine()) != null) { ... }
因为这是阻塞读取。 null 表示 EOF,它还没有出现。
您正在尝试实现一种协议,其中一方可以发送任意数量的行,但您仍然希望在 Java 程序中同步执行读取和写入。发送一个字符串"your turn"让对方知道一堆消息已经发完是一种出路。不确定您真正想要实现的是什么
TLDR;有没有一种友好的方式让 Java 从 ROOT stdout 读取?反之亦然?
我有一个启动 ROOT 进程的 Java 函数。 Java 和 ROOT 然后通过标准输入和标准输出进行通信。好吧,这就是计划。出于某种原因,我无法通过 Java 进程访问 cin
(ROOT) 输出的任何信息。
我确定我在这里偶然发现了几个同时存在的陷阱,很抱歉这个问题太长了,包含的代码尽可能简单
根代码:
void test_io(){
while (true){
string in_str;
cout << "ROOT:: loop iteration";
//cout.flush(); flushing has no effect
cin >> in_str;
cout << "ROOT:: received string " << in_str;
}
}
我运行此代码使用以下命令:
root -b -q external/test_io.C
输出如下:
------------------------------------------------------------
| Welcome to ROOT 6.02/05 http://root.cern.ch |
| (c) 1995-2014, The ROOT Team |
| Built for linuxx8664gcc |
| From tag v6-02-05, 9 February 2015 |
| Try '.help', '.demo', '.license', '.credits', '.quit'/'.q' |
------------------------------------------------------------
root [0]
Processing external/test_io.C...
ROOT:: loop iteration
当我用键盘输入一些文本时,它会以明显的方式工作。
下面是相关的Java代码:
public void start() throws IOException{
/*
Start the process. create buffered reader and writer
*/
System.out.println("Java:: Starting Process...");
oProcess = new ProcessBuilder("root","-b","-q","external/test_io.C").start();
InputStream oIs = oProcess.getInputStream();
InputStreamReader oIsReader = new InputStreamReader(oIs);
oBr = new BufferedReader(oIsReader);
OutputStream oOs = oProcess.getOutputStream();
OutputStreamWriter oOsWriter = new OutputStreamWriter(oOs);
oBw = new BufferedWriter(oOsWriter);
}
public void communicate()throws IOException{
//sends stuff to the process and reads the results...
read_stuff();
write_stuff("message from java. blah blah blah");
read_stuff();
}
private void write_stuff(String sMessage)throws IOException{
System.out.println("Java:: write stuff: "+sMessage);
oBw.write(sMessage);
oBw.write("\n");
oBw.flush();
}
private void read_stuff()throws IOException{
/*
reads stuff from the external process. returns the last line recieved
*/
System.out.println("Java:: read_stuff...");
String sLine;
//wait for it to be ready...
long end=System.currentTimeMillis()+2000;
while ((System.currentTimeMillis() < end)){
if (oBr.ready())
break;
}
if (!oBr.ready()){
System.out.println("Java:: NOT READY :/");
return;
}
System.out.println("Java:: READY!!!");
while ((sLine = oBr.readLine()) != null) {
System.out.println("Java:: ...got line: " + sLine);
}
return;
}
调用 start
然后 communicate
产生以下输出:
Java:: Starting Process...
Java:: read_stuff...
Java:: READY!!!
Java:: ...got line: ------------------------------------------------------------
Java:: ...got line: | Welcome to ROOT 6.02/05 http://root.cern.ch |
Java:: ...got line: | (c) 1995-2014, The ROOT Team |
Java:: ...got line: | Built for linuxx8664gcc |
Java:: ...got line: | From tag v6-02-05, 9 February 2015 |
Java:: ...got line: | Try '.help', '.demo', '.license', '.credits', '.quit'/'.q' |
Java:: ...got line: ------------------------------------------------------------
Java:: ...got line:
Java:: ...got line:
Java:: ...got line: Processing external/test_io.C...
然后它阻塞了。 Java 甚至没有收到行 'ROOT:: loop iteration'.
如有任何帮助或指导,我们将不胜感激。我所有的谷歌搜索和实验都一无所获。
编辑
将 cout
语句更改为:cout << "stuff" << endl;
让事情变得更好一些。我的 java 程序输出现在看起来像:
Java:: Starting Process...
Java:: read_stuff...
Java:: READY!!!
Java:: ...got line: ------------------------------------------------------------
Java:: ...got line: | Welcome to ROOT 6.02/05 http://root.cern.ch |
Java:: ...got line: | (c) 1995-2014, The ROOT Team |
Java:: ...got line: | Built for linuxx8664gcc |
Java:: ...got line: | From tag v6-02-05, 9 February 2015 |
Java:: ...got line: | Try '.help', '.demo', '.license', '.credits', '.quit'/'.q' |
Java:: ...got line: ------------------------------------------------------------
Java:: ...got line:
Java:: ...got line:
Java:: ...got line: Processing external/test_io.C...
Java:: ...got line: ROOT:: loop iteration
然后阻塞。
从 ROOT 代码中删除行 cin >> in_str;
会导致 Java 生成以下无限内容:
Java:: ...got line: ROOT:: loop iteration
Java:: ...got line: ROOT:: recieved string
Java:: ...got line: ROOT:: loop iteration
...etc
所以现在的问题是cin
...
C++ 输出语句没有换行符,不会刷新行。
cout << "ROOT:: loop iteration" << endl;
cin >> in_str;
cout << "ROOT:: received string " << in_str << endl;
另一个问题是 cin 从不 "sees" 从 Java 程序发送的行。你从不执行
System.out.println("Java:: write stuff: "+sMessage);
等等
cin >> in_str;
块。 Java 程序块在
while ((sLine = oBr.readLine()) != null) { ... }
因为这是阻塞读取。 null 表示 EOF,它还没有出现。
您正在尝试实现一种协议,其中一方可以发送任意数量的行,但您仍然希望在 Java 程序中同步执行读取和写入。发送一个字符串"your turn"让对方知道一堆消息已经发完是一种出路。不确定您真正想要实现的是什么