2014-12-07 3 views
0

Я хочу отправить некоторую строку дочернему процессу и их, и это вернет меня в верхнем регистре. Идея в том, что я помещаю пустую строку, оба процесса прекратятся. В первый раз работает все отлично, но в следующий раз процесс застрянет во второй раз, и мне нужно заставить закрыть.JAVA - отправка данных дочернему процессу в цикле

Отец код ->

public class padre { 
public static void main(String[] args){ 
    System.out.println("Soy el padre"); 
    try { 
     Process p = Runtime.getRuntime().exec("java -jar C:\\Users\\Cristian\\Desktop\\hijo.jar"); 

     InputStreamReader isr = new InputStreamReader(System.in); 
     BufferedReader escritorPadre = new BufferedReader(isr); 

     //Leer del hijo 
     BufferedReader brHijo = new BufferedReader(new InputStreamReader(p.getInputStream())); 
     BufferedReader brHijoError = new BufferedReader(new InputStreamReader(p.getErrorStream())); 
     //EScribir en el hijo 
     OutputStream os = p.getOutputStream(); 


     String lineaConsola; 
     while((lineaConsola = escritorPadre.readLine()).isEmpty() == false){ 

      lineaConsola +="\n"; 
      os.write(lineaConsola.getBytes()); 
      os.flush(); 


      String linea; 
      while((linea = brHijo.readLine()) != null){ 
       System.out.println(linea); 
       System.out.println("Atascado en el while del padre"); 
      } 
      while((linea = brHijoError.readLine()) != null){ 
       System.out.println(linea); 
       System.out.println("Atascado en el while del padre error"); 
      } 

     } 






    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 

} 

}

код для детей ->

public class hijo { 
public static void main(String[] args){ 
    InputStreamReader in = new InputStreamReader(System.in); 
    BufferedReader br = new BufferedReader(in); 
    String linea; 
    try { 
     while(!(linea = br.readLine()).isEmpty()){ 
      System.out.println("Hijo -> " + linea.toUpperCase()+"\n"); 
      System.out.println("Atascado en el while del hijo"); 
     } 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
} 

}

+1

** Почему ** взять на себя затраты на запуск нескольких JVM вместо вызова другого метода в одном? –

+0

И вам не нужна пустая строка. Простое закрытие выходного потока приведет к завершению потока во входном потоке дочернего процесса. Тебе ничего не нужно. – EJP

ответ

0

У вас есть несколько проблем здесь.

  • Во-первых, в ваших основных циклах (как для отца, так и для сына) вы не проверяете окончание файла. Это означает, что вы можете получить null от считывателя потока, и при попытке доступа к isEmpty() вы получите NullPointerException.

  • Во-вторых, вы никогда не передаете пустую строку процессу сына, потому что, как только линия, которую вы получаете от escritorPadre.readLine(), пуста, вы выходите из цикла while. Таким образом, сын, проверяющий isEmpty(), бесполезен. Было бы лучше закрыть поток сыну, как только вы выйдете (вам всегда нужно закрыть потоки, когда вы закончите с ними, так или иначе), и обработайте null со стороны сына.

  • Но самое главное: ваша петля для чтения от сына всегда будет застревать, потому что вы получите только null со стороны сына на конце потока. И вы получите только конец потока, если сын использует close() в своем потоке (или заканчивается сын). Но если вы использовали close() со стороны сына, вы не сможете снова написать стандартный вывод.

    Итак, ваша петля продолжает ждать, пока сын напишет что-то еще, и сын ждет, когда отец напишет что-нибудь еще, прежде чем что-то что-то напишет. Таким образом, процесс находится в тупике.

Вы можете решить, что сын должен отправить специальный выход (пустую строку), чтобы вы знали, когда прекратить чтение его вывода.

Но тогда у вас есть проблема со стандартной ошибкой. После того, как вы закончите чтение с выхода сына, вы начнете читать стандартную ошибку. Таким образом, чтобы вы могли покинуть этот цикл, вам также придется распечатать пустую строку до стандартной ошибки после каждой записи на выходе, а также добавить пустую строку в трассировку стека, которая будет напечатана с каждого catch. Затем вам также нужно будет добавить чек на пустую строку в петле отца, читая стандартную ошибку сына.

Лично я считаю, что это не очень элегантно. Но это выполнимо.

В любом случае, чтобы вы начали, со стороны отца вы должны убедиться, что вы закрываете все потоки и проверяете нулевое значение при чтении.Что-то вроде:

try { 
    p = Runtime.getRuntime().exec("java -jar C:\\Users\\Cristian\\Desktop\\hijo.jar"); 
} catch (IOException e) { 
    e.printStackTrace(); 
    return; 
} 

// Use try-with-resources to open all the streams and readers 
// so that they will be closed automatically 
try (
    BufferedReader escritorPadre = new BufferedReader(new InputStreamReader(System.in)); 

    //Leer del hijo 
    BufferedReader brHijo = new BufferedReader(new InputStreamReader(p.getInputStream())); 
    BufferedReader brHijoError = new BufferedReader(new InputStreamReader(p.getErrorStream())); 
    //EScribir en el hijo 
    OutputStream os = p.getOutputStream(); 
) { 

    String lineaConsola; 

    // Read until either end-of-file or empty line 
    while((lineaConsola = escritorPadre.readLine()) != null && ! lineaConsola.isEmpty()){ 

     ... // I ommitted the reading from the son until you decide how you want to arrange it. 

    } 

} catch (IOException e) { 
    // TODO Auto-generated catch block 
    e.printStackTrace(); 
} 

И в сыне, а также убедитесь, чтобы закрыть все ресурсы или использовать примерочных с-ресурсами, и проверьте, как нуль и пустая строка:

try (
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 
){ 
    while((linea = br.readLine()) != null && ! linea.isEmpty()){ 
     System.out.println("Hijo -> " + linea.toUpperCase()+"\n"); 
     System.out.println("Atascado en el while del hijo"); 
     // Decide how you want to handle telling the father that output is done 
    } 
} catch (IOException e) { 
    // TODO Auto-generated catch block 
    e.printStackTrace(); 
} 
Смежные вопросы