2012-05-10 29 views
8

अन्य भाषाओं में (जैसे bash और पायथन), जब हम एक बच्चे की प्रक्रिया को जन्म देते हैं, तो यह नई प्रक्रिया माता-पिता से stdout और stderr का उत्तराधिकारी होगा। इसका मतलब है कि बाल प्रक्रिया से कोई भी आउटपुट टर्मिनल के साथ-साथ माता-पिता से आउटपुट पर मुद्रित किया जाएगा।जावा प्रक्रिया में मुख्य प्रक्रिया stdout/stderr में बाल प्रक्रिया stdout/stderr को पुनर्निर्देशित करने के लिए कैसे करें?

हम जावा में एक ही व्यवहार कैसे प्राप्त कर सकते हैं?

मेरे पहली कोशिश थी:

proc = Runtime.getRuntime().exec(cmd); 

लेकिन यह काम नहीं करेगा। पर this answer और this answer आधार पर, मैं के साथ कोड बदल दिया है:

ProcessBuilder pb = new ProcessBuilder(cmd); 
pb.redirectOutput(System.out); 
pb.redirectError(System.err); 

लेकिन यह भी संकलन नहीं करता है, के रूप में बहस की उम्मीद विधि मानकों के साथ असंगत हैं।

उत्तर

13

आपको आपके द्वारा बनाई गई प्रक्रिया के आउटपुट और त्रुटि स्ट्रीम को पढ़ने और आउटपुट को लिखने की आवश्यकता है जहां आप इसे जाना चाहते हैं (आपके मामले में System.out और System.err)।

संपादित करें। इसके बाद के संस्करण जवाब यह संभव हुआ लग रहा है के बजाय फोन करने के लिए

processBuilder.redirectOutput(Redirect.INHERIT) 
+1

तुम्हारा मतलब है कि मैं करने की जरूरत है एक लूप को लागू करें जो सिर्फ एक स्ट्रीम से पढ़ता रहता है और दूसरे में लिखता रहता है? क्षमा करें, व्यवहार्य नहीं है। बहुत अधिक काम (शायद एक नए धागे में चलने की आवश्यकता है, और यह संभव बग के बहुत सारे अंक पेश करता है)। –

+2

व्यवहार्य या यह आवश्यक नहीं था। मैंने अभी जावा 7 एपीआई की जांच की है और ऐसा लगता है कि इसे संबोधित किया गया है - अब आप रीडायरेक्ट.इनहेरिट में रीडायरेक्ट आउटपुट को कॉल कर सकते हैं जो आप चाहते हैं कि हासिल करने के लिए देखता है। – henry

1

यह निश्चित रूप से संभव है जावाडोक से जावा 7 की < 7. के रूप में के लिए सही है। चींटी सेट सही होने पर चींटी जावा कार्य ऐसा करता है। मुझे सभी विवरण याद नहीं हैं, लेकिन एक त्वरित रूप से ऐसा लगता है कि अधिकांश जादू PumpStreamHandler में है। आप उससे कुछ प्रेरणा खोजने का प्रयास कर सकते हैं।

+1

उस से असल में आसान है, लेकिन केवल 1.7 में लागू होता है, जो आप प्रसंस्करण Builder.redirectOutput() का उपयोग कर रहे हैं, क्योंकि आप pb.redirectOutput (Redirect.INHERIT) करना चाहते हैं। हालांकि मैंने कभी ऐसा नहीं किया है। – asudell

3

यह बहुत बुरा नहीं है। मैं शुरू में कहा "आसान", तो मुझे एहसास हुआ कि मैं InputStreamConsumer कोड करने के लिए था:

public static class InputStreamConsumer extends Thread { 

    private InputStream is; 

    public InputStreamConsumer(InputStream is) { 
     this.is = is; 
    } 

    @Override 
    public void run() { 

     try { 
      int value = -1; 
      while ((value = is.read()) != -1) { 
       System.out.print((char)value); 
      } 
     } catch (IOException exp) { 
      exp.printStackTrace(); 
     } 
    } 
} 

private void captureOutput(Process p) { 

    InputStreamConsumer stdout; 
    InputStreamConsumer errout; 

    errout = new InputStreamConsumer(p.getErrorStream()); 
    stdout = new InputStreamConsumer(p.getInputStream()); 
    errout.start(); 
    stdout.start(); 
} 

.... कुछ तरह के अंदर चल रहा है ...

ProcessBuilder pb = new ProcessBuilder("cmd.exe", "/D", "/C", myCommand, parm, parm...); 
    try { 
     System.out.println("Start "+myCommand); 
     Process myProcess = pb.start(); 
     captureOutput(myProcess); 

     int returnCode = myProcess.waitFor(); 
     System.out.println("myProcess: return code : "+returnCode); 
    } 
    catch (IOException e) { 
     e.printStackTrace(); 
    } 
+0

अन्य लोगों ने आईडीई को छोड़कर मेरे लिए काम नहीं किया। यह एक किया, धन्यवाद। – Steve

+1

अच्छा लगता है - लेकिन क्या हमें ऐसे स्व-कार्यान्वित कोड का उपयोग करना है? STDERR को STDOUT में रीडायरेक्ट करने के लिए जावा में कोई समर्थन नहीं है और फिर एक इनपुट-स्ट्रीम से उनके संयोजन को पढ़ने के लिए? – SomethingSomething

संबंधित मुद्दे