Искам да използвам външен инструмент, докато извличам някои данни (преминаване през линии). За това първо използвах Runtime.getRuntime().exec(), за да го изпълня. Но тогава извличането ми стана много бавно. Така че търся възможност за изпълнение на външния инструмент във всеки екземпляр на цикъла, използвайки същия екземпляр на shell.
Разбрах, че трябва да използвам ProcessBuilder. Но все още не работи.
Ето моя код за тестване на изпълнението (с вход от отговорите тук във форума):
public class ExecuteShell {
ProcessBuilder builder;
Process process = null;
BufferedWriter process_stdin;
BufferedReader reader, errReader;
public ExecuteShell() {
String command;
command = getShellCommandForOperatingSystem();
if(command.equals("")) {
return; //Fehler! No error handling yet
}
//init shell
builder = new ProcessBuilder( command);
builder.redirectErrorStream(true);
try {
process = builder.start();
} catch (IOException e) {
System.out.println(e);
}
//get stdout of shell
reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
errReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
//get stdin of shell
process_stdin = new BufferedWriter(new OutputStreamWriter(process.getOutputStream()));
System.out.println("ExecuteShell: Constructor successfully finished");
}
public String executeCommand(String commands) {
StringBuffer output;
String line;
try {
//single execution
process_stdin.write(commands);
process_stdin.newLine();
process_stdin.flush();
} catch (IOException e) {
System.out.println(e);
}
output = new StringBuffer();
line = "";
try {
if (!reader.ready()) {
output.append("Reader empty \n");
return output.toString();
}
while ((line = reader.readLine())!= null) {
output.append(line + "\n");
return output.toString();
}
if (!reader.ready()) {
output.append("errReader empty \n");
return output.toString();
}
while ((line = errReader.readLine())!= null) {
output.append(line + "\n");
}
} catch (Exception e) {
System.out.println("ExecuteShell: error in executeShell2File");
e.printStackTrace();
return "";
}
return output.toString();
}
public int close() {
// finally close the shell by execution exit command
try {
process_stdin.write("exit");
process_stdin.newLine();
process_stdin.flush();
}
catch (IOException e) {
System.out.println(e);
return 1;
}
return 0;
}
private static String getShellCommandForOperatingSystem() {
Properties prop = System.getProperties( );
String os = prop.getProperty( "os.name" );
if ( os.startsWith("Windows") ) {
//System.out.println("WINDOWS!");
return "C:/cygwin64/bin/bash";
} else if (os.startsWith("Linux") ) {
//System.out.println("Linux!");
return"/bin/sh";
}
return "";
}
}
Искам да го нарека в друг клас като този Testclass:
public class TestExec{
public static void main(String[] args) {
String result = "";
ExecuteShell es = new ExecuteShell();
for (int i=0; i<5; i++) {
// do something
result = es.executeCommand("date"); //execute some command
System.out.println("result:\n" + result); //do something with result
// do something
}
es.close();
}
}
Проблемът ми е, че изходният поток винаги е празен:
ExecuteShell: Constructor successfully finished
result:
Reader empty
result:
Reader empty
result:
Reader empty
result:
Reader empty
result:
Reader empty
Прочетох темата тук: Java процес с входно/изходен поток
Но кодовите фрагменти не бяха достатъчни, за да продължа, нещо ми липсва. Всъщност не съм работил много с различни теми. И не съм сигурен дали/как скенерът ми е полезен. Наистина ще се радвам на малко помощ.
В крайна сметка целта ми е да извикам външна команда многократно и да я направя бързо.
РЕДАКТИРАНЕ: Промених цикъла, така че es.close() да е отвън. И исках да добавя, че не искам само това вътре в цикъла.
РЕДАКТИРАНЕ: Проблемът с времето беше, че командата, която извиках, предизвика грешка. Когато командата не предизвиква грешка, времето е приемливо.
Благодаря ви за отговорите