0

我正在尝试使用 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) {}

...

4

2 回答 2

1

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

  • 构建你的外部程序命令行
  • 构建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 {
  // ...
}

流渲染.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();
  }
}
于 2013-09-11T05:49:05.380 回答
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

于 2013-09-11T05:49:50.497 回答