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