通过ProcessBuilder创建postgresql的备份

时间:2016-05-11 14:05:05

标签: java postgresql processbuilder

我想在java中使用pg_dump创建数据库的备份。备份的创建工作正常,但在程序退出之前无法启动。

有没有办法立即开始备份?

public static void backupDb() throws IOException, InterruptedException {
  String path = "C:\\HACENE\\test.backup";
  Runtime r = Runtime.getRuntime();
  //PostgreSQL variables    
  String host = "localhost";
  String user = "postgres";
  String dbase = "gtr_bd";
  String password = "postgres";
  Process p;
  ProcessBuilder pb;

  r = Runtime.getRuntime();
  pb = new ProcessBuilder("C:\\Program Files\\PostgreSQL\\9.3\\bin\\pg_dump", "-v", "-h", host, "-f", path, "-U", user, dbase);
  pb.environment().put("PGPASSWORD", password);
  pb.redirectErrorStream(true);
  p = pb.start();
  System.out.println("end of backup");
}

3 个答案:

答案 0 :(得分:0)

您应该检查从Process返回的ProcessBuilder.start()实例的状态。正如评论中已经提到的,您可以使用Process.waitFor()方法等待该过程完成。此外,您应该考虑检查已启动进程的退出值,以确定备份是否成功。

这就是我在我的一个项目中所做的:

private void validateExitValue(final Process aProcess, final String aCommand,
    final String aResult) throws IllegalStateException {
    do {
        try {
            if (aProcess.waitFor() != 0) {
                final String errorMessage = String.format("Command '%s' terminated with exit status '%s': %s",
                    aCommand, aProcess.exitValue(), aResult);
                throw new IllegalStateException(errorMessage);
            }
            break;
        } catch (final InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    } while (true);
}

如果进程以IllegalStateException以外的退出代码结束,此方法将等待进程完成并抛出0

当我的Java程序终止时,当前启动备份进程的观察结果只是巧合,我怀疑,因为启动备份过程很可能是Java程序执行的最后一个操作。启动外部进程将花费一些时间,程序将继续并终止,即看起来该进程是在Java程序终止时启动的。

答案 1 :(得分:0)

// Comment -> p = pb.start();
// add this at the end:

final Process process = pb.start();  
InputStream is = process.getInputStream();  
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line;
while ((line = br.readLine()) != null) {
  System.out.println(line);
}
// because you put "-v" in your command. Another way is to remove "-v" from your command

-v指定详细模式。这将导致pg_dump向转储文件输出详细的对象注释和开始/停止时间,并将消息转换为标准错误。从LINK

开始

答案 2 :(得分:0)

如果在cmd中执行此命令,则可以正常工作:

"C:\Program Files\PostgreSQL\9.3\bin\pg_dump.exe" -U postgres -h localhost -p 5432 database_name > "C:\Test\test.buckup"

所以你可以将这些行放在这样的.bat文件中:

@echo off
cd "C:\Program Files\PostgreSQL\9.3\bin\" 
pg_dump.exe -U postgres -h localhost -p 5432 bd_suivi > "C:\Test\test.buckup"
exit

使用java执行此file.bat,如下所示:

public static void main(String[] args) {
    try {
        ProcessBuilder builder = new ProcessBuilder("cmd.exe", "/c", "start script.bat");
        builder.redirectErrorStream(true);
        Process p = builder.start();
        BufferedReader r = new BufferedReader(new InputStreamReader(p.getInputStream()));
        String line;
        while (true) {
            line = r.readLine();
            if (line == null) {
                break;
            }
            System.out.println(line);
        }
        System.out.println("I finished the creation of the buckup!");
    } catch (Exception e) {
        System.out.println("Exception = " + e);
    }
}
祝你好运。