Как закрыть дескриптор файла стандартного дочернего процесса Java в Windows, пока потомки все еще живут - PullRequest
2 голосов
/ 30 марта 2011

Имеется простой пакетный файл c1.bat, содержащий:

start notepad 1> nul 2> nul
exit

и программа на Java:

import java.io.InputStream;

public class ProcessTest {

    public static void main(String[] args) throws Exception {
        ProcessBuilder b = new ProcessBuilder();
        b.command("c1.bat");
        Process p = b.start();
        new Thread(new ProcDrain(p)).start();
        System.out.println("Parent process finished: " + p.waitFor());
    }

    private static class ProcDrain implements Runnable {
        private final Process p;

        private ProcDrain (Process p) {
            this.p = p;
        }

        @Override
        public void run() {
            try {
                InputStream in = p.getInputStream();
                while (in.read() >= 0) { }
                System.out.println("Inputstream drainer finished");
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    }
}

Первый процесс, который выполняет c1.bat, быстро завершается, порождая другой процесс (блокнот). Однако поток слива блокируется в вызове read () и не завершается, пока блокнот не будет закрыт. Это говорит о том, что блокнот держит открытый дескриптор файла stdout исходного процесса, несмотря на то, что пакетный файл перенаправил его.

Есть ли какой-нибудь способ для командного файла закрыть дескрипторы файла stdout / stderr, чтобы поток-сток не блокировал read () после фактического завершения порожденного процесса?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...