2008-09-13 19 views
28

में के साथ एक प्रक्रिया शुरू अगर मैं जावा के ProcessBuilder वर्ग के माध्यम से एक प्रक्रिया शुरू, मैं में है कि इस प्रक्रिया के मानक, मानक बाहर के लिए पूरा उपयोग, और जावा InputStreams और OutputStreams के रूप में मानक त्रुटि स्ट्रीम नहीं है। हालांकि, मुझे उन धाराओं को System.in, System.out, और System.err पर सहजता से कनेक्ट करने का कोई तरीका नहीं मिल रहा है।विरासत में मिला stdin/stdout/stderr जावा 6

यह redirectErrorStream() उपयोग करने के लिए एक एकल InputStream कि उपप्रक्रिया के मानक बाहर होता है और मानक त्रुटि, और बस पाश है कि के माध्यम से प्राप्त है और मेरे मानक के माध्यम से इसे भेजने के लिए संभव है बाहर लेकिन मुझे लगता है कि इसके लिए कोई तरीका नहीं मिल रहा है और दे सकते हैं उपयोगकर्ता प्रक्रिया में टाइप करता है, क्योंकि अगर वह सी system() कॉल का उपयोग करता है तो वह कर सकता है।

यह जावा एसई 7 में संभव है जब यह आता है-मैं बस सोच रहा हूं कि अब कोई कामकाज है या नहीं। बोनस अंक यदि बच्चे की प्रक्रिया में isatty() का परिणाम पुनर्निर्देशन के माध्यम से होता है।

+0

क्षमा करें मैं मदद नहीं कर सकता। – jjnguy

+0

कोई समस्या नहीं है। (मैं वह नहीं था जिसने आपको रास्ते में गिरा दिया था।) –

+0

हे, ठीक है, उस लड़के को धन्यवाद जिसने मुझे बिना मतदान के वोट दिया। और धन्यवाद, जॉन मुझे कम करने के लिए नहीं। – jjnguy

उत्तर

15

आपको सिस्टम संस्करणों में Process आउट, गलती और इनपुट स्ट्रीम कॉपी करने की आवश्यकता होगी। ऐसा करने का सबसे आसान तरीका Commons IO पैकेज से IOUtils कक्षा का उपयोग कर रहा है। copy method आपको जो चाहिए वह दिखता है। प्रतिलिपि विधि आमंत्रण अलग धागे में होना चाहिए।

यहाँ बुनियादी कोड है:

// Assume you already have a processBuilder all configured and ready to go 
final Process process = processBuilder.start(); 
new Thread(new Runnable() {public void run() { 
    IOUtils.copy(process.getOutputStream(), System.out); 
} }).start(); 
new Thread(new Runnable() {public void run() { 
    IOUtils.copy(process.getErrorStream(), System.err); 
} }).start(); 
new Thread(new Runnable() {public void run() { 
    IOUtils.copy(System.in, process.getInputStream()); 
} }).start(); 
+4

काफी नहीं। IOUtils.copy इनपुटस्ट्रीम लेता है क्योंकि यह पहला तर्क है, इसलिए getOutputStream के साथ काम नहीं करेगा। तो यह IOUtils.copy है (process.getInputStream(), System.out); यह थोड़ी उलझन में है, क्योंकि GetOutputStream वास्तव में प्रक्रिया के इनपुट के लिए पाइप करता है। – Eelco

+0

इसकी संरचना सही दिखती है, लेकिन मैं यह भी मानता हूं कि IOUtil के पैरामीटर बैकवर्ड्स लगता है। process.getInputStream() को stdout पर पाइप किया जाना चाहिए (हाँ, यह पीछे की ओर लगता है)। इसलिए जब इसकी संरचना अच्छी लगती है, तो IOUtils की कॉल गलत लगती है और अब मुझे थोड़ा उलझन में डाल दिया गया है ... – titania424

+1

गलत। यह सिर्फ ** पाइप ** माता-पिता और बच्चे के इनपुट/आउटपुट स्ट्रीम के बीच डेटा, इसे ** ** ** प्राप्त करने की अनुमति नहीं देता है। उदाहरण के लिए यदि जावा कमांड टर्मिनल पर शुरू किया गया था (सी isatty() == true, या System.console()! = Null) बच्चा खुद को टर्मिनल में चलाने के रूप में नहीं देख पाएगा, क्योंकि इसकी इनपुट/आउटपुट स्ट्रीम पाइप हैं यह महत्वपूर्ण है क्योंकि टर्मिनल में चलने पर कुछ (अधिकांश) प्रोग्राम अलग-अलग व्यवहार करते हैं। जावा 7 की ProcessBuilder.Redirect.INHERIT इस संबंध में सही तरीके से काम करता है। – Tobia

13

जॉन जवाब पर एक बदलाव है कि संकलित करता है तथा कॉमन्स आईओ उपयोग करने के लिए आप की आवश्यकता नहीं है:

private static void pipeOutput(Process process) { 
    pipe(process.getErrorStream(), System.err); 
    pipe(process.getInputStream(), System.out); 
} 

private static void pipe(final InputStream src, final PrintStream dest) { 
    new Thread(new Runnable() { 
     public void run() { 
      try { 
       byte[] buffer = new byte[1024]; 
       for (int n = 0; n != -1; n = src.read(buffer)) { 
        dest.write(buffer, 0, n); 
       } 
      } catch (IOException e) { // just exit 
      } 
     } 
    }).start(); 
} 
+0

System.in के लिए प्रश्न का उत्तर नहीं दें। – solotim

+0

पाइप क्यों है (System.in, process.getOutputStream()); काम नहीं लग रहा है? –

3

System.in के लिए निम्नलिखित के बजाय pipein() का उपयोग pipe()

pipein(System.in, p.getOutputStream()); 

कार्यान्वयन:

private static void pipein(final InputStream src, final OutputStream dest) { 

    new Thread(new Runnable() { 
     public void run() { 
      try { 
       int ret = -1; 
       while ((ret = System.in.read()) != -1) { 
        dest.write(ret); 
        dest.flush(); 
       } 
      } catch (IOException e) { // just exit 
      } 
     } 
    }).start(); 

} 
+0

यह काम नहीं कर सकता है। –

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