bufferedreader - Java wrapper for ROOT. OutputStreamReader is blocking -
tldr; there friendly way java read root stdout? , vice versa?
i have java function launches root process. java , root communicate via stdin , stdout. well, that's plan anyway. reason can't info output cin(root) accessible via java process.
i'm sure i've stumbled upon several simultanious gotchas here, sorry long question, code included simple possible
root code:
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;     } }   i run code following command:
root -b -q external/test_io.c   the output looks like:
   ------------------------------------------------------------   | welcome root 6.02/05                http://root.cern.ch |   |                               (c) 1995-2014, root team |   | built linuxx8664gcc                                    |   | tag v6-02-05, 9 february 2015                         |   | try '.help', '.demo', '.license', '.credits', '.quit'/'.q' |    ------------------------------------------------------------  root [0]  processing external/test_io.c... root:: loop iteration   when enter text keyboard works in obvious way.
now here relevant java code:
public void start() throws ioexception{         /*         start process. create buffered reader , 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 process , reads results...         read_stuff();         write_stuff("message 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 external process. returns last line recieved         */         system.out.println("java:: read_stuff...");         string sline;          //wait 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;     }   calling start communicate yields following output:
java:: starting process... java:: read_stuff... java:: ready!!! java:: ...got line:    ------------------------------------------------------------ java:: ...got line:   | welcome root 6.02/05                http://root.cern.ch | java:: ...got line:   |                               (c) 1995-2014, root team | java:: ...got line:   | built linuxx8664gcc                                    | java:: ...got line:   | 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...   and blocks. java doesn't receive line 'root:: loop iteration'.
any or direction appreciated. googling , experimentation has come blank.
edit
changing cout statements like: cout << "stuff" << endl; makes things little better. java program out put looks like:
java:: starting process... java:: read_stuff... java:: ready!!! java:: ...got line:    ------------------------------------------------------------ java:: ...got line:   | welcome root 6.02/05                http://root.cern.ch | java:: ...got line:   |                               (c) 1995-2014, root team | java:: ...got line:   | built linuxx8664gcc                                    | java:: ...got line:   | 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   then blocks.
removing line cin >> in_str; root code causes java generate following infinite stuff:
java:: ...got line: root:: loop iteration java:: ...got line: root:: recieved string  java:: ...got line: root:: loop iteration ...etc   so problem cin...
the c++ output statements without newlines, not flush lines.
cout << "root:: loop iteration" << endl;   cin >> in_str; cout << "root:: received string " << in_str << endl;   the other problem cin never "sees" line sent java program. never execute
system.out.println("java:: write stuff: "+smessage);   and
cin >> in_str;   blocks. java program blocks in
while ((sline = obr.readline()) != null) { ... }   because blocking read. null indicates eof, isn't here yet.
you trying implement protocol 1 side can send arbitrary number of lines, still want execute reads , writes synchronously in java program. sending string "your turn" let other side know bunch of messages has been finished 1 way out. not sure want implement, though
Comments
Post a Comment