【问题标题】:Database restoring with java code - program not responding使用 java 代码恢复数据库 - 程序没有响应
【发布时间】:2013-09-11 03:55:50
【问题描述】:

我正在尝试使用 Java 程序恢复备份的 .sql 文件。我在下面发布方法。但是当我执行这个程序时,程序会停止很长时间。然后我在命令行(Windows)中执行了相同的 mysql 命令,效果很好。

困惑于我错过的地方。你怎么看 ?

            File file;
         final JFileChooser fc = new JFileChooser();
         int returnVal = fc.showOpenDialog(this);

   if (returnVal == JFileChooser.APPROVE_OPTION) {
                 file = fc.getSelectedFile();

         try {
             System.out.println(file.getCanonicalPath());

        String executeCmd = "mysql -u " + username + " -p" + password +" " + dbName+" < "+" \" "+file.getCanonicalPath()+"\" " ;
         Process runtimeProcess;
           runtimeProcess = Runtime.getRuntime().exec(executeCmd);
         int processComplete = runtimeProcess.waitFor();
         if (processComplete == 0) {

            JOptionPane.showMessageDialog(Interface.mainFrame, "Database Backup restored successfully.", "Netmetering", 1);     
        } else {
            System.out.println("Could not restore the backup");
        }
    } catch (IOException | InterruptedException ex) {}

...

【问题讨论】:

  • 进程可能正在等待它的标准输出被刷新,你忽略了。读取进程输入流直到它返回 -1
  • 对不起,我不确定我是否理解你。它需要永远完成。但是当我在 cmd 中调用相同的命令时,大约需要 2 秒才能完成。
  • @MadProgrammer 我认为你是对的。谢谢。 Apache Commons Exec 库可能是一个解决方案。我会试试的。

标签: java mysql database restore


【解决方案1】:
String executeCmd = "mysql -u " + username + " -p" + password +" " + dbName+" < "+" \" "+file.getCanonicalPath()+"\" " ;
Process runtimeProcess = Runtime.getRuntime().exec(executeCmd);
InputStream is = runtimeProcess.getInputStream();

// Do one OR the other, but not both ;)

// If you don't care about the output, but I think it's a bit of waste personally...
while (is.read() != -1) {}

// I'd at least dump the output to the console...
int byteRead = -1;
while ((byteRead = is.read()) != -1) {
    System.out.print((char)byteRead );
}

int processComplete = runtimeProcess.waitFor();
if (processComplete == 0) {...}

我还建议使用ProcessBuilder 而不是像这样手动创建Process,它可以更好地处理参数 - 恕我直言

【讨论】:

    【解决方案2】:

    一般来说,运行外部程序的正确方法是:

    • 构建你的外部程序命令行
    • 构建ProcessBuilderProcess
    • 构建您自己的 StreamRender
    • 执行您的外部程序
    • 检查外部程序的 STDOUT 和 STDERR
    • 验证外部程序的退出状态

    您可以按如下所述实现此序列:

    String command = "mysql -u... -p... dbname < file.sql";
    ProcessBuilder pb = new ProcessBuilder(command);
    Process pr;
    
    try {
      pr = pb.start();
      StreamRender outputStdout = new StreamRender(pr.getInputStream(), StreamRender.STDOUT);
      // your STDOUT output here
      outputStdout.start();
    
      StreamRender outputStderr = new StreamRender(pr.getErrorStream(), StreamRender.STDERR);
      // your STDERR outpu here
      outputStderr.start();
    
      pr.waitFor();
      if (pr.exitValue() != 0) {
        // your external program fails
      } else {
        // ok, your external program was executed correctly
      }
    
    } catch (Exception e) {
      // ...
    }  finally {
      // ...
    }
    

    StreamRender.java

    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    
    public class StreamRender extends Thread {
    
    public static final String STDOUT = "STDOUT";
    public static final String STDERR = "STDERR";
    
    private InputStream inputStream;
    private String inputType;
    
    public StreamRender(InputStream inputStream, String inputType) {
      this.inputStream = inputStream;
      this.inputType = inputType;
    }
    
    public void run() {
      try {
        InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
        BufferedReader br = new BufferedReader(inputStreamReader);
        String line = null;
        while ((line = br.readLine()) != null) {
          System.out.println(this.inputType + " > " + line);
        }
      } catch (IOException ioe) {
        ioe.printStackTrace();
      }
    }
    

    【讨论】:

    • 小心使用BufferedReader,并不是每个进程都会在生命周期过程中输出一个新的行终止符,如果幸运的话,它会在最后这样做;)
    • @Cristian Porta 非常感谢。这很有帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-13
    • 2014-01-25
    • 2014-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多