#java #runtime.exec
#java #runtime.exec
Вопрос:
Я использую process = Runtime.getRuntime().exec(cmd,null,new File(path));
для выполнения некоторого SQL в файле (abz.sql)
Команда является:
"sqlplus " context.getDatabaseUser() "/"
context.getDatabasePassword() "@"
context.getDatabaseHost() ":"
context.getDatabasePort() "/"
context.getSid() " @"
"""
script """;
String path=context.getReleasePath() "/Server/DB Scripts";
Он выполняет этот файл, но не получает exit. Поэтому я попытался использовать:
Writer out = new OutputStreamWriter(process.getOutputStream());
out.append("commit;rn");
out.append("exit rn");
System.out.println("---------" out);
out.close();
Это завершающий блок, который я использую:
if(context.getConnectionField()=="ORACLE")
{
String cmd=
"sqlplus " context.getDatabaseUser() "/"
context.getDatabasePassword() "@"
context.getDatabaseHost() ":"
context.getDatabasePort() "/"
context.getSid() " @"
"""
script """;
String path=context.getReleasePath() "/Server/DB Scripts";
process = Runtime.getRuntime().exec(cmd,null,new File(path));
out = new OutputStreamWriter(process.getOutputStream());
out.append("commit;rn");
out.append("exit rn");
System.out.println("---------" out);
out.close();
Integer result1 = null;
while (result1 == null) {
try {
result1 = process.waitFor();
}
catch (InterruptedException e) {}
}
if(process.exitValue() != 0)
return false;
return true;
}
Комментарии:
1. Если вы серьезно относитесь к этому, пожалуйста, подумайте, как другие прочтут ваш вопрос; ваш вопрос плохо отформатирован и его очень трудно прочитать другим. Обычно это приводит к ответам низкого качества или вообще к отсутствию ответов. Если вы хотите получить правильные ответы на свой вопрос, пожалуйста, попробуйте написать свои вопросы соответствующим образом
![]()
2. Каким образом это не работает? Вы не получаете ожидаемых результатов или получаете исключения и т.д.?
Ответ №1:
Показанному коду не удается прочитать поток ошибок Process
. Это может блокировать прогресс. ProcessBuilder
был представлен в Java 1.5 и имеет удобный метод для redirectErrorStream()
— так что необходимо использовать только один поток.
Для получения более общих советов прочитайте и реализуйте все рекомендации, когда Runtime.exec() не будет.
Комментарии:
1. @krico: Да. На самом деле я думал, что OP делает это, но поскольку это
out.close()
происходит раньшеprocess.waitFor()
,OutputStream
это не используется должным образом.
Ответ №2:
Я вижу здесь несколько проблем. Используемая вами версия ‘exec’ будет маркировать командную строку с помощью StringTokenizer, поэтому необычные символы в пароле (например, пробелы) или другие заменяемые параметры являются случайностями, ожидающими своего часа. Я рекомендую переключиться на версию
Процесс exec(строка[] cmdarray, строка [] envp, каталог файла) вызывает исключение IOException
Это немного сложнее в использовании, но гораздо надежнее.
Вторая проблема в том, что существуют всевозможные оговорки относительно того, будет ли exec выполняться одновременно с процессом Java (см. http://download.oracle.com/javase/1.4.2/docs/api/java/lang/Process.html). Итак, вам нужно указать, в какой операционной системе вы работаете. Если это не выполняется одновременно, то ваша стратегия записи в выходной поток не может работать!
Последняя часть программы написана довольно неясно. Я предлагаю …
for (;;) {
try {
process.waitFor();
return process.exitValue() == 0;
} catch ( InterruptedException _ ) {
System.out.println( "INTERRUPTED!" ); // Debug only.
}
}
Это устраняет лишнюю переменную result1, устраняет лишний блок и подчеркивает возможную причину бесконечного цикла.
Надеюсь, это поможет и удачи!