barbitoff programmer`s blog

Здесь я публикую заметки из программерской жизни: грабли, на которые мне случилось наступить, проблемы, для которых было найдено элегантное (или не очень) решение, а также все, с чем мне пришлось столкнуться и чем хотелось бы поделиться =)
PS Если хотите меня поблагодарить - на странице есть 3 места, чтобы это сделать =)
Показаны сообщения с ярлыком Runtime. Показать все сообщения
Показаны сообщения с ярлыком Runtime. Показать все сообщения

вторник, 4 августа 2015 г.

JDK 1.6: баг при передаче unicode-символов с использованием Runtime.exec()

В JDK 6 имеется баг, поправленный только в 7ой версии, связанный с передачей unicode-символов при вызове Runtime.exec(). Например, т.н. "правые двойные кавычки" при таком вызове превращаются в обычные прямые двойные кавычки (хотя бывают и более неприятные кейсы, когда вызов вообще падает с Exception-ом).
Благо, для проблемы есть workaround, основанный на замене Runtime.exec() на использование ProcessBuilder. Ниже приведен пример вызова, взятый со stackoverflow:
String[] cmd = new String[]{"yourcmd.exe", "some argument with unicode characters"};      
Map<String, String> newEnv = new HashMap<String, String>();
newEnv.putAll(System.getenv());
String[] i18n = new String[cmd.length + 2];
i18n[0] = "cmd";
i18n[1] = "/C";
i18n[2] = cmd[0];
for (int counter = 1; counter < cmd.length; counter++)
{
    String envName = "JENV_" + counter;
    i18n[counter + 2] = "%" + envName + "%";
    newEnv.put(envName, cmd[counter]);
}
cmd = i18n;
ProcessBuilder pb = new ProcessBuilder(cmd);
Map<String, String> env = pb.environment();
env.putAll(newEnv);
final Process p = pb.start();

понедельник, 31 декабря 2012 г.

Java: получение вывода, выданного запущенным bat-ником

Уже как-то писал, как из Java вызывать bat-ники, теперь расскажу, как получить после этого то, что bat-ник вывел в "консоль".
Делается это так:
Process proc = Runtime.getRuntime().exec("cmd /c start my.bat");
proc.waitFor();
ByteArrayOutputStream bos = new ByteArrayOutputStream();
IOUtils.copy(proc.getInputStream(), bos);
String batOutput = new String(bos.toByteArray(),"Cp866");
Здесь используется класс IOUtils из commons-io. Результат получаем в переменной  batOutput.