-1

TLDR; Java に ROOT stdout から読み取らせるフレンドリーな方法はありますか? およびその逆?

ROOT プロセスを起動する Java 関数があります。Java と ROOT は、stdin と stdout を介して通信します。まあ、それはとにかく計画です。cin何らかの理由で、Java プロセス経由でアクセスできる (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...

4

1 に答える 1

0

C++ 出力ステートメントには改行がないため、行がフラッシュされません。

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

もう 1 つの問題は、cin が Java プログラムから送信された行を「認識」しないことです。あなたは決して実行しません

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

そして、

cin >> in_str;

ブロック。Java プログラムブロック

while ((sLine = oBr.readLine()) != null) { ... }

これはブロッキング読み取りであるためです。null は、まだここにない EOF を示します。

一方が任意の行数を送信できるプロトコルを実装しようとしていますが、Java プログラムで同期的に読み取りと書き込みを実行したいと考えています。「あなたの番」という文字列を送信して、一連のメッセージが終了したことを相手に知らせるのが 1 つの方法です。あなたが本当に実装したいものがわからない

于 2015-06-01T12:57:54.533 に答える