Вызов сценария оболочки из зависания Java - PullRequest
1 голос
/ 06 августа 2010

Итак, я пытаюсь выполнить сценарий оболочки, который выдает много выходных данных (в сотнях мегабайт) из файла Java.Это приводит к зависанию процесса и никогда не завершается.

Однако в сценарии оболочки, если я перенаправляю вывод сценария в какой-либо файл журнала или / dev / null, файл Java выполняется и завершается в один миг.

Это из-за объема данных, которые Java-программа никогда не завершает?Если да, есть ли документация как таковая?или есть ли ограничения на количество данных (задокументировано)?

Вот как вы можете смоделировать этот сценарий.

Файл Java будет выглядеть так:Сценарий «a-script-which-outputs-huuggee-data.sh» может выглядеть следующим образом:

#!/bin/sh
# Toggle the line below
exec 3>&1 > /dev/null 2>&1

count=1
while [ $count -le 1000 ]
do
        cat some-big-file
        ((count++))
done

echo
echo Yes I m done

Бесплатное пиво для правильного ответа.:)

Ответы [ 3 ]

5 голосов
/ 06 августа 2010

Это потому, что вы не читаете с выхода Process.

Согласно классу 'Javadocs , если вы не сделаете этого, то можете получитьтупик;процесс заполняет свой буфер ввода-вывода и ожидает, пока «оболочка» (или процесс прослушивания) прочитает из него и очистит его.Между тем, ваш процесс, который должен это делать, блокирует ожидание завершения процесса.

Вы захотите вызвать getInputStream () и надежно читать его (возможно, из другого потока).), чтобы остановить блокировку процесса.

Также взгляните на Пять ловушек Java-процессов и Когда Runtime.exec () не будет - обе информативные статьи об общихпроблемы с Process.

2 голосов
/ 06 августа 2010

Вы никогда не читаете входной поток, поэтому он, вероятно, блокируется, потому что входной буфер заполнен.

0 голосов
/ 06 августа 2010

Буфер ввода / вывода имеет ограниченный размер (в зависимости от операционной системы). Если я правильно помню, это был не большой или Windows XP по крайней мере. Попробуйте создать поток, который читает InputStream как можно быстрее.

Что-то вроде этого:

class StdInWorker
            implements Worker
    {
        private BufferedReader br;
        private boolean run = true;
        private int linesRead = 0;

        private StdInWorker (Process prcs)
        {
            this.br = new BufferedReader(
                    new InputStreamReader(prcs.getInputStream()));
        }

        public synchronized void run ()
        {
            String in;
            try {
                while (this.run) {
                    while ((in = this.br.readLine()) != null) {
                        this.buffer.add(in);
                        linesRead++;
                    }

                    Thread.sleep(50);
                }
            }
            catch (IOException ioe) {
                ioe.printStackTrace();
            }
            catch (InterruptedException ie) {}
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...