"إذا أراد العامل أن يؤدي عمله بشكل جيد، فعليه أولاً أن يشحذ أدواته." - كونفوشيوس، "مختارات كونفوشيوس. لو لينجونج"
الصفحة الأمامية > برمجة > كيفية تحقيق إعادة توجيه المخرجات غير المحظورة لـ ProcessBuilder؟

كيفية تحقيق إعادة توجيه المخرجات غير المحظورة لـ ProcessBuilder؟

تم النشر بتاريخ 2024-12-13
تصفح:103

How to Achieve Non-Blocking Output Redirection for ProcessBuilder?

إعادة توجيه المخرجات غير المحظورة لـ ProcessBuilder

لتنفيذ العمليات في Java، يوفر ProcessBuilder أسلوبًا مناسبًا. ومع ذلك، ينشأ التحدي عندما نحتاج إلى إعادة توجيه تدفقات stdout وstderr للعملية المنفذة إلى System.out بشكل غير متزامن.

إعادة التوجيه غير المتزامن باستخدام مؤشر الترابط

إحدى الطرق الشائعة يتضمن إنشاء مؤشر ترابط جديد يدويًا يقرأ باستمرار من stdOut ويكتب إلى System.out. على الرغم من كونه وظيفيًا، إلا أن هذا الأسلوب ينشئ أعباء إضافية لإدارة سلاسل الرسائل.

الحل الأنيق مع ProcessBuilder.inheritIO

إذا كان Java 7 أو إصدار أحدث متاحًا، فإن ProcessBuilder يوفر حلاً أبسط وأكثر أناقة. الحل: ProcessBuilder.inheritIO. تقوم هذه الطريقة بتعيين تدفقات الإدخال / الإخراج القياسية للعملية الفرعية لترث تلك الخاصة بعملية Java الأصلية.

يعد استخدام inheritIO أمرًا مباشرًا:

Process p = new ProcessBuilder().inheritIO().command("command1").start();

بديل لجافا السابقة الإصدارات

بالنسبة لإصدارات Java الأقدم من الإصدار 7، يمكن استخدام التنفيذ التالي:

import java.io.*;
import java.util.Scanner;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class NonBlockingOutputRedirection {
    public static void main(String[] args) throws Exception {
        ExecutorService executorService = Executors.newSingleThreadExecutor();
        Process p = Runtime.getRuntime().exec("cmd /c dir");
        inheritIO(p.getInputStream(), System.out, executorService);
        inheritIO(p.getErrorStream(), System.err, executorService);
    }

    private static void inheritIO(final InputStream src, final PrintStream dest, ExecutorService executorService) {
        executorService.execute(() -> {
            Scanner scanner = new Scanner(src);
            while (scanner.hasNextLine()) {
                dest.println(scanner.nextLine());
            }
        });
        executorService.shutdown();
    }
}

مزايا هذه الطريقة

توفر هذه الطريقة العديد من المزايا:

  • غير متزامن: تحدث إعادة توجيه الإخراج في الخلفية، وتحرير الخيط الرئيسي.
  • الإنهاء التلقائي للخيط: عند اكتمال العملية الفرعية، يتم حذف الخيوط سيتم إنهاء المسؤول عن إعادة توجيه الإخراج تلقائيًا بسبب نهاية الملف على تدفقات الإدخال.

بشكل عام، باستخدام ProcessBuilder.inheritIO في Java 7 أو الأحدث، أو التنفيذ البديل للإصدارات السابقة، يوفر طريقة نظيفة وفعالة لتحقيق إعادة توجيه المخرجات بدون حظر للعمليات التي بدأت باستخدام ProcessBuilder.

أحدث البرنامج التعليمي أكثر>

تنصل: جميع الموارد المقدمة هي جزئيًا من الإنترنت. إذا كان هناك أي انتهاك لحقوق الطبع والنشر الخاصة بك أو الحقوق والمصالح الأخرى، فيرجى توضيح الأسباب التفصيلية وتقديم دليل على حقوق الطبع والنشر أو الحقوق والمصالح ثم إرسالها إلى البريد الإلكتروني: [email protected]. سوف نتعامل مع الأمر لك في أقرب وقت ممكن.

Copyright© 2022 湘ICP备2022001581号-3