Java ProcessBuilder: результирующий процесс зависает

Я искал решение той же проблемы, за исключением того, что мне нужна цепочка; например,

"CamelCamelCamelCase" -> "Camel-camel-camel-case"

. Исходя из хороших двухсловных решений здесь, я придумал следующее:

"-".join(x.group(1).lower() if x.group(2) is None else x.group(1) \
         for x in re.finditer("((^.[^A-Z]+)|([A-Z][^A-Z]+))", "stringToSplit"))

. Большая часть сложной логики заключается в том, чтобы избегать нижнего индекса первого слова , Вот более простая версия, если вы не возражаете изменить первое слово:

"-".join(x.group(1).lower() for x in re.finditer("(^[^A-Z]+|[A-Z][^A-Z]+)", "stringToSplit"))

Конечно, вы можете предварительно скомпилировать регулярные выражения или присоединиться к подчеркиванию вместо дефиса, как описано в других решениях .

32
задан Matt D 19 July 2010 в 21:54
поделиться

4 ответа

Если процесс пишет в stderr или stdout , а вы его не читаете - он просто «зависнет», блокируя при записи в стандартный вывод / ошибка . Либо перенаправьте stdout / err в / dev / null с помощью оболочки, либо объедините stdout / err с redirectErrorStream (true) и создайте другой поток, который читает из ] stdout процесса

35
ответ дан 27 November 2019 в 20:24
поделиться

Другое решение состоит в том, чтобы запустить процесс с Redirect.PIPE и закрыться InputStream как это:

ProcessBuilder builder = new ProcessBuilder(cmd);
builder.redirectOutput(Redirect.PIPE);
builder.redirectErrorStream(true); // redirect the SysErr to SysOut
Process proc = builder.start();
proc.getInputStream().close(); // this will close the pipe and the output will "flow"
procp.waitFor();

я протестировал это в Windows и Linux и работах!

0
ответ дан 27 November 2019 в 20:24
поделиться

Хотите трюк ?

Не запускайте процесс из ProcessBuilder.start () . Не пытайтесь возиться с перенаправлением / потреблением потока из Java (особенно, если вам это наплевать;)

Используйте ProcessBuilder.start () , чтобы запустить небольшой сценарий оболочки, который пожирает все потоки ввода / вывода.

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

#!/bin/bash

nohup $1 >/dev/null 2>error.log &

То есть: если вас не волнует stdout, но вы все еще хотите записать stderr (не так ли?) В файл ( error.log здесь).

Если вас даже не интересует stderr, просто перенаправьте его на stdout:

#!/bin/bash

nohup $1 >/dev/null 2>1 &

И вы вызываете этот крошечный скрипт из Java, передавая ему в качестве аргумента имя процесса, который вы хотите запустить.

Если процесс, работающий в Linux, который перенаправляет как stdout, так и stderr в / dev / null, по-прежнему производит что-нибудь , значит, у вас сломанная, несовместимая установка Linux;)

В Другими словами: приведенное выше Just Works [TM] и избавьтесь от проблемного «вам необходимо использовать потоки в том или ином порядке, бла-бла-бла, специфичная для Java бессмысленность» .

12
ответ дан 27 November 2019 в 20:24
поделиться

Изменить: меня не беспокоит поток ввода-вывода, созданный из процесса, и поэтому я не предпринял никаких шагов для решения этой проблемы - может ли это вызвать зависание самого процесса?

. Если вы не читаете выходные потоки, созданные процессом, возможно, что приложение заблокируется после заполнения буферов приложения. Я никогда не видел, чтобы это происходило в Linux (хотя я не говорю, что это не так), но я видел именно эту проблему в Windows. Я думаю, это, скорее всего, связано.

2
ответ дан 27 November 2019 в 20:24
поделиться
Другие вопросы по тегам:

Похожие вопросы: