#java #processbuilder
#java #processbuilder
Вопрос:
У меня есть пакетный скрипт, который принимает входные данные в виде имени пользователя и возраста и печатает оба входных данных. Я хочу написать Java-программу для выполнения этого скрипта и передачи входных данных.
Я написал Java-программу с помощью ProcessBuilder. Я также передаю имя пользователя и возраст в поток вывода процесса, но печатается только имя пользователя, а возраст отсутствует.
мой скрипт (файл test.bat) :
@echo off
echo executing test.bat
set /p name=Enter Name:
set /p age=Enter Age :
echo Hi %name%, you are %age% years old.
моя Java-программа :
private static void executeInteractiveCommand(String cmd,String ... args){
try{
List<String> command = new ArrayList<String>();
command.add(cmd);
ProcessBuilder builder = new ProcessBuilder(command);
Map<String, String> environ = builder.environment();
final Process process = builder.start();
OutputStream out = process.getOutputStream();
out.write("tester nr".getBytes());
out.flush();
out.write("25n".getBytes());
out.flush();
out.close();
int errCode = process.waitFor();
System.out.println("Process Error Code : " errCode);
InputStream is = process.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
//out.close();
is.close();
System.out.println("Program terminated!");
}catch(IOException ex){
ex.printStackTrace();
} catch(InterruptedException ex){
ex.printStackTrace();
}
}
Комментарии:
1. вот результат: код ошибки процесса java TestScript: 0 выполнение теста.bat Введите имя: Введите возраст: Привет, тестировщик, тебе много лет. Программа завершена!
Ответ №1:
Таким образом, вы сбрасываете два входа отдельно в свой пакетный скрипт и закрываете поток. В результате скрипт использует только первый ввод. И поскольку поток тогда закрыт, он просто пусто вернет все оставшиеся SET /P
операторы, игнорируя реальные входные данные, оставшиеся в канале. И вопрос: почему?
Я нашел эту статью, в которой подробно анализируется, как SET /P
работает команда, и какие условия существуют для завершения одного сеанса ввода запроса.
Последние 2 прочитанных символа — CRLF
Это обычный случай и предпочтительный. Если ввод не передается по каналу, а вводится пользователем, ввод завершается при нажатии клавиши ввода. Затем были установлены токены CRLF, и входные данные будут использованы. В нашем Java-канале мы должны быть в состоянии сделать то же самое, добавив rn
в конце String
. Но почему-то это не работает, и я не мог понять, почему.
Тайм-аут
Очень простой обходной путь, который я мог бы вам предоставить, — это просто подождать некоторое время между вводами. Результатом будет то, что скрипт использует каждый ввод перед следующим. Поэтому, если вы добавите
Thread.sleep(1000);
между вашими двумя входами все будет работать так, как ожидалось.
полный буфер
Ввод одного SET /P
оператора ограничен 1024 символами. Мы можем использовать это, чтобы решить ситуацию, передав буфер размером на один символ меньше 1024. Таким образом, первый символ следующего ввода заполнит буфер, что приведет к потреблению входных данных и переходу к следующему оператору. Итак, если вы используете этот метод преобразования
public static byte[] convert(String str){
byte[] asBytes = str.getBytes();
byte[] result = new byte[1023];
for(int i = 0; i < asBytes.length; i )
result[i] = asBytes[i];
return resu<
}
Ваш код будет работать так, как ожидалось. На самом деле вы даже можете не выполнять очистку.
OutputStream out = process.getOutputStream();
out.write(convert("tester"));
out.write(convert("25"));
out.close();
Комментарии:
1. Спасибо за вашу помощь. после перевода в режим ожидания я получаю желаемый результат.
2. @RajeshKumar На самом деле да. Я провел некоторое исследование. Смотрите мое редактирование.
Ответ №2:
вы можете попробовать приведенный ниже код
'Runtime runtime = Runtime.getRuntime();
Process proc = null;
String executionarr[] = { batchfileName, arg1, arg2};
proc = runtime.exec(executionarr);'
в вашем пакетном файле вы можете прочитать первый аргумент с %1, второй с %2 и так далее.