【问题标题】:how to redirect stdin to java Runtime.exec?如何将标准输入重定向到 java Runtime.exec?
【发布时间】:2010-04-01 20:10:08
【问题描述】:

我想使用 Java 的 Runtime.exec 方法执行一些 sql 脚本。我打算调用 mysql.exe / mysql.sh 并将脚本文件重定向到这个进程。 从命令提示符我可以运行命令

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

我可以使用 Runtime.exec 调用 mysql.exe 但如何将数据从 sql 文件重定向到 mysql.exe ?


看了http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html?page=4的文章,使用了StreamGobbler机制来获取错误和输出流。那里没问题。问题在于使用 BufferedReader 读取文件“scripts\create_tables.sql”并将内容传递给进程的输出流。我期待进程将数据传递给 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,其他无错误或输出。

【问题讨论】:

    标签: java redirect stdin runtime.exec


    【解决方案1】:

    Exec 返回一个 Process 对象给你。

    Process 有 getInputStream 和 getOutputStream 方法。

    只需使用它们来获取输入流并开始将字节塞入其中。不要忘记读取输出流,否则进程可能会阻塞。

    【讨论】:

    • 当然还有错误流。或者使用 ProcessBuilder 的 redirectErrorStream(boolean) 方法合并输出和错误流,并读取合并的流。
    【解决方案2】:

    重定向是 OS shell/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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-09
      • 1970-01-01
      • 1970-01-01
      • 2020-02-06
      • 2016-04-26
      • 1970-01-01
      相关资源
      最近更新 更多