2015-06-01 3 views
-1

TLDR; есть ли дружеский способ заставить Java читать из ROUT stdout? И наоборот?Java-обертка для ROOT. OutputStreamReader блокирует

У меня есть функция Java, которая запускает процесс ROOT. Java и ROOT затем обмениваются данными через stdin и stdout. Ну, это план в любом случае. По какой-то причине я не могу получить какой-либо информационный вывод на cin (ROOT) для доступа через Java-процесс.

Я уверен, что я наткнулся на несколько Simultanious подводных камней здесь, жаль длинный вопрос, код включен как можно проще

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».

Любая помощь или руководство будут оценены. Все мои поисковые запросы и эксперименты стали пустым.

EDIT

Изменение cout заявления выглядеть следующим образом: cout << "stuff" << endl; делает вещи немного лучше. Моя программа java out put теперь выглядит так:

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 

Тогда блоки.

Удаление строки cin >> in_str; из кода Корневые причины в Java, чтобы генерировать следующий бесконечный материал:

Java:: ...got line: ROOT:: loop iteration 
Java:: ...got line: ROOT:: recieved string 
Java:: ...got line: ROOT:: loop iteration 
...etc 

Так что проблема в настоящее время cin ...

+0

Сундуки должны сопровождаться комментариями. Таким образом, сообщество становится лучше (в противоположность раздраженному) – Sheena

+1

Операторы вывода C++ не имеют символов новой строки, которые не будут стирать строки. Кроме того, код Java должен читать C++. – laune

+0

@laune: спасибо, это решает половину проблемы. Я не уверен, что вы подразумеваете под «кормить чтение C++». Я подробно изложил свои изменения и их результаты в приведенном выше правиле. – Sheena

ответ

0

выходные заявления C++ являются не символами новой строки, которые не будут смывать линии.

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

Другая проблема заключается в том, что cin никогда не видит линию, отправленную из программы Java. Вы никогда не выполнить

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

и так блоки

cin >> in_str; 

.Программа Java блокирует в

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

потому что это блокировка чтения. null указывает EOF, которого еще нет.

Вы пытаетесь реализовать протокол, в котором одна сторона может отправлять произвольное количество строк, но вы все равно хотите выполнять чтение и запись синхронно в программе Java. Отправка строки «ваша очередь», чтобы другая сторона узнала, что куча сообщений была закончена, - это один выход. Не уверен, что вы действительно хотите реализовать, хотя

 Смежные вопросы

  • Нет связанных вопросов^_^