بدء عملية باستخدام stdin/stdout/stderr الموروثة في Java 6

StackOverflow https://stackoverflow.com/questions/60302

  •  09-06-2019
  •  | 
  •  

سؤال

إذا بدأت عملية عبر Java ProcessBuilder فئة، لدي حق الوصول الكامل إلى تدفقات الأخطاء القياسية الداخلية والخارجية والقياسية لهذه العملية مثل Java InputStreams و OutputStreams.ومع ذلك، لا يمكنني العثور على طريقة لربط هذه التدفقات بسلاسة System.in, System.out, ، و System.err.

من الممكن استخدامها redirectErrorStream() للحصول على واحد InputStream يحتوي على الخطأ القياسي للعملية الفرعية والخطأ القياسي، وما عليك سوى تكرار ذلك وإرساله من خلال المخرج القياسي الخاص بي - ولكن لا يمكنني العثور على طريقة للقيام بذلك والسماح للمستخدم بالكتابة في العملية، كما يستطيع هو أو هي إذا استخدمت C system() يتصل.

يبدو أن هذا ممكنًا في Java SE 7 عندما يتم طرحه — أتساءل فقط عما إذا كان هناك حل بديل الآن.نقاط المكافأة إذا كانت نتيجة isatty() في عملية الطفل يحمل من خلال إعادة التوجيه.

هل كانت مفيدة؟

المحلول

سوف تحتاج إلى نسخ عملية تدفقات الخروج والخطأ والإدخال إلى إصدارات النظام.أسهل طريقة للقيام بذلك هي استخدام IOUtils فئة من حزمة Commons IO.ال طريقة النسخ يبدو أن ما تحتاجه.يجب أن تكون استدعاءات طريقة النسخ في سلاسل رسائل منفصلة.

هنا هو الكود الأساسي:

// 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();

نصائح أخرى

هناك تباين في إجابة جون يجمع ولا يتطلب منك استخدام Commons IO:

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();
}

ل 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();

}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top