Я хочу выполнить некоторые sql сценарии с помощью метода Java Runtime.exec. Я намереваюсь вызвать mysql.exe / mysql.sh и перенаправить файл сценария к этому процессу. От командной строки я могу выполнить команду
-p < scripts\create_tables.sql
Я могу вызвать mysql.exe с помощью Runtime.exec, но как я перенаправляю данные от sql файла до mysql.exe?
Я прочитал статью в http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html?page=4 и использовал механизм StreamGobbler для получения потоков сообщений об ошибках и потоков вывода. Никакая проблема там. Проблема возникает в чтении файла "scripts\create_tables.sql" использование BufferedReader и передачу содержания к outputstream prcess. Я ожидал, что Процесс передаст данные mysql.exe. Но я вижу, что только первая строка читается из этого sql файла.
OutputStream outputstream = proc.getOutputStream();
OutputStreamWriter outputstreamwriter = new OutputStreamWriter(outputstream);
BufferedWriter bufferedwriter = new BufferedWriter(outputstreamwriter);
while ( (line = br.readLine()) != null)
{
bufferedwriter.write(line);
bufferedwriter.flush();
System.out.println(line);
}
bufferedwriter.flush();
bufferedwriter.close();
proc.waitFor()
Когда я делаю это, я вижу, что только первая строка в create_tables.sql выполняется. Код выхода для процесса 0 и нет другой никакой ошибки или вывода.
Exec возвращает вам объект Process.
У Process есть методы getInputStream и getOutputStream.
Просто используйте их, чтобы получить входной поток и начать запихивать в него байты. Не забудьте прочитать выходной поток, иначе процесс может заблокироваться.
Перенаправление - это функция среды оболочки / cmd ОС. Чтобы вызвать их правильно, мы должны использовать Runtime.exec (String []) вместо Runtime.exec (String). Вот код.
public Result executeCmd(String[] cmds, boolean waitForResult)
{
Result result = new Result();
result.output = "";
try
{
for(int i=0;i<cmds.length;i++)
{
System.out.println("CMD["+i+"]::"+cmds[i]);
}
System.out.println("");
Process process = null;
if(cmds.length > 1)
process=Runtime.getRuntime().exec(cmds);
else
process=Runtime.getRuntime().exec(cmds[0]);
if (waitForResult)
{
StreamGobbler errordataReader = new StreamGobbler(process
.getErrorStream(), "ERROR");
StreamGobbler outputdataReader = new StreamGobbler(process
.getInputStream(), "OUTPUT");
errordataReader.start();
outputdataReader.start();
int exitVal = process.waitFor();
errordataReader.join();
outputdataReader.join();
result.returnCode = exitVal;
result.output = outputdataReader.output;
result.error = errordataReader.output;
}
}
catch (Exception exp)
{
result.exp = exp;
result.returnCode = -1;
}
return result;
}
И вызовите этот метод, используя
Result result = executeCmd(cmds, true);
, где
CMD[0]::cmd
CMD[1]::/c
CMD[2]::.\mysql\bin\mysql --host=<hostname> --port=<portNum> -u <userName> < .\scripts\create_tables.sql