运行时 - exec使用mysqldump JAVA转储数据库

时间:2013-09-30 03:30:02

标签: java runtime.exec

我正在尝试使用mysqldump和java为我的数据库创建转储。

我已经完成了代码,但条件if(processCompleted == 0)从未因某些我无法理解的原因而发生。我这样说是因为在控制台上没有例外,但它总是打印

  

“执行转储时出错!”

这使我得出结论,如果(processCompleted == 0)永远不会满足。

有人可以解释一下我在这里做错了吗?

public boolean backupDatabase(String path, String whichServer)
{
    String cmd;
    Process runtimeProcess;

    if(whichServer.equalsIgnoreCase("local"))
    {
        cmd = "mysqldump -u " + getSourceUsername() + " -p" + getSourceServerPassword()
            + " --add-drop-database -B " + getSourceDatabase() + " -r " + path;
    }         
    else if(whichServer.equalsIgnoreCase("remote"))
    {
        cmd = "mysqldump -u " + getDestinationUsername() + " -p" + getDestinationServerPassword()
            + " --add-drop-database -B " + getDestinationDatabase() + " -r " + path;
    }
    else
    {
        System.out.println("Input server incorrect");
        return false;
    }

    try{

        String[] cmdArray = new String[]{"C:\\wamp\\bin\\mysql\\mysql5.5.24\\bin\\mysqldump.exe", cmd};
        System.out.println("Preparing for dump.");
        runtimeProcess = Runtime.getRuntime().exec(cmdArray);

        int processCompleted = runtimeProcess.waitFor();

        if(processCompleted == 0)
        {
            System.out.println("Dump done!");
            return true;
        }
        else
        {
            System.out.println("Error doing dump!");
        }

    } catch(Exception ex)
    {
        System.out.println("Exception -> " + ex.getMessage());
    }
    return false;

}

这是我使用@MadProgrammer建议的代码:

public boolean backupDatabase(String path, String whichServer) 
{

    List<String> args = new ArrayList<String>();
    args.add("C:\\wamp\\bin\\mysql\\mysql5.5.24\\bin\\mysqldump.exe");

    args.add("-u");
    args.add(getSourceUsername());
    args.add("-p");
    args.add(getSourceServerPassword());
    args.add("--add-drop-database");
    args.add("-B");
    args.add(getSourceDatabase());
    args.add("-r");
    args.add(path);

    try{
        ProcessBuilder pb = new ProcessBuilder(args);
        pb.redirectError();
        Process p = pb.start();

        InputStream is = p.getInputStream();

        int in = -1;

        while((in = is.read()) != -1)
        {
            System.out.println((char) in);
        }

        int proccessCompleted = p.waitFor();

        if(proccessCompleted == 0)
        {
            System.out.println("Dump done!");
            return true;
        }
        else
        {
            System.out.println("Error doing dump!");
            return false;
        }
    }
    catch(IOException | InterruptedException ex)
    {
        System.out.println("Exception exportDB -> " + ex.getMessage() + "|" + ex.getLocalizedMessage());
    }
    return false;
}

PS;在哪里写了“//?这是一个命令吗?” -p是密码的命令,getSourceServerPassword()是获取密码的方法。

1 个答案:

答案 0 :(得分:2)

我怀疑是因为你已经将cmdArray分成只有两个mysqldump将第二个数组元素视为单个命令行参数的元素。

此外,您没有注意过程的输出,这使您很难确定处理过程中的内容。

你的“基础”命令还包括mysqldump ...

"mysqldump -u " + getSourceUsername() + " -p" + getSourceServerPassword()
        + " --add-drop-database -B " + getSourceDatabase() + " -r " + path;

作为命令的一部分,这意味着您实际上正在调用mysqldump mysqldump ...

而不是使用String,而是将所有命令放入某种列表中。

请记住,如果它被命令行上的空格分隔,则它是一个单独的命令/元素

List<String> args = new ArrayList<String>
args.add("C:\\wamp\\bin\\mysql\\mysql5.5.24\\bin\\mysqldump.exe");
//...
args.add("-u");
args.add(getSourceUsername());
args.add("-p" + getSourceServerPassword()); //?? Is this a single command?
args.add("--add-drop-database");
args.add("-B");
args.add(getSourceDatabase());
args.add("-r");
args.add("path);
//...

然后使用ProcessBuilder

ProcessBuilder pb = new ProcessBuilder(args);
pb.redirectError();
Process p = pb.start();

InputStream is = p.getInputStream();
int in = -1;
while ((in = is.read()) != -1) {
    System.out.print((char)in);
}

int processCompleted = p.waitFor();

请记住,您永远不应忽略进程的输出,即使您不关心,也应尝试使用InputStream中的内容,因为如果未读取输出流,某些进程将挂起。