ROOT的Java包装器。 OutputStreamReader阻塞

时间:2015-06-01 09:38:26

标签: java bufferedreader root-framework

TLDR;是否有一种友好的方式让Java从ROOT标准读取?反之亦然?

我有一个启动ROOT流程的Java函数。然后Java和ROOT通过stdin和stdout进行通信。好吧,无论如何,那是计划。由于某种原因,我无法通过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 ...

1 个答案:

答案 0 :(得分:0)

C ++输出语句没有换行符,不会刷新行。

cout << "ROOT:: loop iteration" << endl;  
cin >> in_str;
cout << "ROOT:: received string " << in_str << endl;

另一个问题是,cin从来没有&#34;看到&#34;从Java程序发送的一行。你永远不会执行

System.out.println("Java:: write stuff: "+sMessage);

cin >> in_str;

块。

中的Java程序阻塞
while ((sLine = oBr.readLine()) != null) { ... }

因为这是阻止读取。 null表示EOF,这里还没有。

您正在尝试实现一个协议,其中一方可以发送任意数量的行,但您仍然希望在Java程序中同步执行读取和写入。发送一个字符串&#34;你的回合&#34;让对方知道一堆消息已经完成是一条出路。不知道你真正想要实现什么,但