2010-04-01 23 views
5

Quiero ejecutar algunos scripts sql usando el método Runtime.exec de Java. Tengo la intención de invocar mysql.exe/mysql.sh y redirigir el archivo de script a este proceso. Desde el símbolo del sistema que se puede ejecutar el comandocómo redirigir stdin a java Runtime.exec?

<mysqInstallDir\/bin\mysql.exe -u <userName> -p <password> < scripts\create_tables.sql 

puedo invocar mysql.exe usando Runtime.exec pero ¿cómo puedo redirigir los datos de archivo sql a mysql.exe?


leí el artículo en http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html?page=4 y se utiliza el mecanismo de StreamGobbler para obtener los flujos de error y de salida. No hay problema allí. El problema viene cuando se lee el archivo "scripts \ create_tables.sql" usando BufferedReader y se pasan los contenidos al outputstream de prcess. Esperaba que el Proceso pasara los datos a mysql.exe. Pero veo que solo la primera línea se lee de este archivo 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() 

Cuando hago esto, veo que solo se ejecuta la primera línea en create_tables.sql. El código de salida para el proceso es 0 y no hay otro error o salida.

Respuesta

5

Exec le devuelve un objeto de proceso.

El proceso tiene los métodos getInputStream y getOutputStream.

Simplemente utilícelos para captar la corriente de entrada y comenzar a introducir bytes en ella. No olvide leer el flujo de salida o el proceso puede bloquear.

+0

y la corriente de error, por supuesto. O combine flujos de salida y error con el método redirectErrorStream (booleano) de ProcessBuilder y lea las secuencias fusionadas. –

1

La redirección es una funcionalidad de los entornos shell/cmd del sistema operativo. Para invocarlos correctamente, debemos usar Runtime.exec (String []) en lugar de Runtime.exec (String). Aquí está el código.

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; 
} 

Y llamar a este método usando

Result result = executeCmd(cmds, true); 

donde

CMD[0]::cmd 
CMD[1]::/c 
CMD[2]::.\mysql\bin\mysql --host=<hostname> --port=<portNum> -u <userName> < .\scripts\create_tables.sql 
Cuestiones relacionadas