Java 通过ProcessBuilder创建postgresql的备份

Java 通过ProcessBuilder创建postgresql的备份,java,postgresql,processbuilder,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 h

我想用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");
}

您应该检查从
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);
}
如果进程以非
0
的退出代码结束,则此方法将等待进程完成并抛出
IllegalStateException

我怀疑,备份过程当前在Java程序终止时启动只是巧合,因为启动备份过程很可能是Java程序执行的最后一个操作。启动外部进程将需要一些时间,您的程序将继续并终止,也就是说,该进程似乎是在Java程序终止时启动的

// 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将详细的对象注释和开始/停止时间输出到转储文件,并将进度消息输出到标准错误。如果您在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
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);
    }
}
然后用java执行file.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
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);
    }
}

祝你好运。

p.waitFor()
也许吧?行为取决于所处的操作系统环境。进程执行不是由java本身完成的。因此,由操作系统实际执行您定义并交付执行的流程。还有,距离P程序退出还有多长时间(毫秒、秒、小时)?进程由操作系统处理,因此从逻辑上讲,当我从应用程序启动它时,它应该启动,但当我退出程序时,进程会正确启动