命令带密码参考
Java代码实现国产人大金仓数据库备份还原需求-CSDN博客文章浏览阅读818次,点赞16次,收藏12次。本人在一次项目中,遇到了需要在系统管理中提供给用户备份还原系统数据的功能,由于项目特殊性,项目底层数据库使用了国产人大金仓数据库(版本V8)。由于本人也是第一次使用金仓数据库,所以在功能实现过程中,踩到了一些坑,特此记录一下,共大家参考,避免踩到和我一样的坑。所以:sys_dump -d 数据库名 -h 127.0.0.1 -p 54321 -U root -W 123456 这个指令是有问题的,于是我又打开了命令窗口,调试了指令发现指令语法错误 -W 123456。于是我get到了,便优化了我的指令。https://blog.csdn.net/weixin_44329740/article/details/135764084
导出和导入分sql和dmp ,推荐用dmp,用代码-ksql 命令导入 sql 一旦报错,程序会一直卡 process.waitFor() 那。
官方参数:直接在页面搜相应命令节课
13. sys_dump — KingbaseES产品手册 https://help.kingbase.com.cn/v8/admin/reference/ref-client/sys_dump.html?highlight=sys_dump
6. 附录B:imp导入参数说明 — KingbaseES产品手册 https://help.kingbase.com.cn/v8/admin/reference/exp-imp/appendix-b.html?highlight=imp
一、导出sql版(不推荐)
导入一旦报错,则子线程无返回值,则程序会一直到超时,所以建议采用导出dmp的方式
1、工具类-导出sql
根据驱动类型,选择执行的命令
1)DatabaseUtil 工具类
import cn.hutool.core.util.StrUtil;
import cn.hutool.system.SystemUtil;
import com.fisec.common.enums.DatabaseTypeEnum;import java.util.HashMap;public class DatabaseUtil {/*** 根据数据库驱动类型,获取数据库类型** @param dbDriver* @return*/public static DatabaseTypeEnum getDbType(String dbDriver) {if (dbDriver.startsWith("com.mysql")) {return DatabaseTypeEnum.Mysql;}if (dbDriver.startsWith("com.kingbase")) {return DatabaseTypeEnum.KingBase;}return DatabaseTypeEnum.Unknown;}/*** 获取mysql备份命令** @param dbHost* @param dbName* @param username* @param pwd* @return*/public static String mysqlBackLinuxCmd(String dbHost, String dbName, String username, String pwd) {return String.format("mysqldump -h%s -u%s -p%s -R %s", dbHost,username, pwd, dbName);}/*** 获取mysql备份命令* 切换磁盘需要添加,并奇幻盘符下命令执行** @param dbHost* @param dbName* @param username* @param pwd* @return*/public static String mysqlBackWindowsCmd(String dbHost, String dbName, String username, String pwd) {return String.format("d: && cd D:/Program Files/MySQL/MySQL Server 8.0/bin && .\\mysqldump.exe -h%s -u%s -p%s -R %s", dbHost,username, pwd, dbName);}/*** 获取 人大金仓数据备份命令** @param dbHost* @param dbName* @param username* @param pwd* @return*/public static String mysqlBackCmd(String dbHost, String dbName, String username, String pwd) {if (SystemUtil.getOsInfo().isWindows()) {return mysqlBackWindowsCmd(dbHost, dbName, username, pwd);}return mysqlBackLinuxCmd(dbHost, dbName, username, pwd);}/*** 获取mysql备份命令** @param dbHost* @param dbName* @param username* @param pwd* @return*/public static String mysqlRecoveryWindowsCmd(String dbHost, String dbName, String username, String pwd, String sqlPath) {return String.format("d: && cd D:/Program Files/MySQL/MySQL Server 8.0/bin && .\\mysql.exe -h%s -u%s -p%s %s < %s", dbHost,username, pwd, dbName, sqlPath);}/*** 获取mysql备份命令** @param dbHost* @param dbName* @param username* @param pwd* @return*/public static String mysqlRecoveryLinuxCmd(String dbHost, String dbName, String username, String pwd, String sqlPath) {return String.format("mysql -h%s -u%s -p%s %s < %s", dbHost,username, pwd, dbName, sqlPath);}/*** 获取 人大金仓数据备份命令** @param dbHost* @param dbName* @param username* @param pwd* @return*/public static String mysqlRecoveryCmd(String dbHost, String dbName, String username, String pwd, String sqlPath) {if (SystemUtil.getOsInfo().isWindows()) {return mysqlRecoveryWindowsCmd(dbHost, dbName, username, pwd, sqlPath);}return mysqlRecoveryLinuxCmd(dbHost, dbName, username, pwd, sqlPath);}/*** 获取人大金仓的备份命令* 注:这里路径为 windows 默认路径 ,注版本为 V008R006C008B0014 路径需根据实际情况替换** @param dbHost* @param dbName* @param username* @param pwd* @return*/public static String kingBaseBackWindowsCmd(String dbHost, String dbName, String username, String pwd) {return StrUtil.format("cd C:/Program Files/Kingbase/ES/V8/KESRealPro/V008R006C008B0014/ClientTools/bin && sys_dump.exe \"host={dbHost} port=54321 user={username} password={pwd} dbname={dbName}\"",new HashMap<>() {{put("dbHost", dbHost);put("dbName", dbName);put("username", username);put("pwd", pwd);}});}/*** 获取人大金仓的备份命令 - windows 默认路径 ,注版本为 V008R006C008B0014* 路径需根据实际情况替换* 所有 java 执行 linux命令需添加前缀 /bin/bash -c** @param dbHost* @param dbName* @param username* @param pwd* @return*/public static String kingBaseBackLinuxCmd(String dbHost, String dbName, String username, String pwd) {return StrUtil.format("cd /opt/Kingbase/ES/V8/KESRealPro/V008R006C008B0014/ClientTools/bin && sys_dump \"host={dbHost} port=54321 user={username} password={pwd} dbname={dbName}\"",new HashMap<>() {{put("dbHost", dbHost);put("dbName", dbName);put("username", username);put("pwd", pwd);}});}/*** 获取人大金仓的恢复数据库命令* 注:这里路径为 windows 默认路径 ,注版本为 V008R006C008B0014 路径需根据实际情况替换** @param dbHost* @param dbName* @param username* @param pwd* @return*/public static String kingBaseRecoveryWindowsCmd(String dbHost, String dbName, String username, String pwd, String sqlPath) {return StrUtil.format("cd C:/Program Files/Kingbase/ES/V8/KESRealPro/V008R006C008B0014/ClientTools/bin && ksql.exe -f {sqlPath} \"host={dbHost} port=54321 user={username} password={pwd} dbname={dbName}\"",new HashMap<>() {{put("dbHost", dbHost);put("dbName", dbName);put("username", username);put("pwd", pwd);put("sqlPath", sqlPath);}});}/*** 获取人大金仓的备份命令 - windows 默认路径 ,注版本为 V008R006C008B0014* 路径需根据实际情况替换* 所有 java 执行 linux命令需添加前缀 /bin/bash -c** @param dbHost* @param dbName* @param username* @param pwd* @return*/public static String kingBaseRecoveryLinuxCmd(String dbHost, String dbName, String username, String pwd, String sqlPath) {return StrUtil.format("cd /opt/Kingbase/ES/V8/KESRealPro/V008R006C008B0014/ClientTools/bin && ksql -f {} \"host={dbHost} port=54321 user={username} password={pwd} dbname={dbName}\"",new HashMap<>() {{put("dbHost", dbHost);put("dbName", dbName);put("username", username);put("pwd", pwd);put("sqlPath", sqlPath);}});}/*** 获取 人大金仓数据备份命令** @param dbHost* @param dbName* @param username* @param pwd* @return*/public static String kingBaseBackCmd(String dbHost, String dbName, String username, String pwd) {if (SystemUtil.getOsInfo().isWindows()) {return kingBaseBackWindowsCmd(dbHost, dbName, username, pwd);}return kingBaseBackLinuxCmd(dbHost, dbName, username, pwd);}/*** 获取 人大金仓数据备份命令** @param dbHost* @param dbName* @param username* @param pwd* @return*/public static String kingBaseRecoveryCmd(String dbHost, String dbName, String username, String pwd, String sqlPath) {if (SystemUtil.getOsInfo().isWindows()) {return kingBaseRecoveryWindowsCmd(dbHost, dbName, username, pwd, sqlPath);}return kingBaseRecoveryLinuxCmd(dbHost, dbName, username, pwd, sqlPath);}/*** 根据数据类型 获取执行的命令** @param databaseTypeEnum* @param dbHost* @param dbName* @param username* @param pwd* @return*/public static String getDbBackCmd(DatabaseTypeEnum databaseTypeEnum, String dbHost, String dbName, String username, String pwd) {return switch (databaseTypeEnum) {case Mysql -> mysqlBackCmd(dbHost, dbName, username, pwd);case KingBase -> kingBaseBackCmd(dbHost, dbName, username, pwd);case Unknown -> null;};}/*** 获取数据的的备份命令** @param dbDriver* @param dbHost* @param dbName* @param username* @param pwd* @return*/public static String getDbBackCmd(String dbDriver, String dbHost, String dbName, String username, String pwd) {return getDbBackCmd(getDbType(dbDriver), dbHost, dbName, username, pwd);}/*** 根据数据类型 获取执行的命令** @param databaseTypeEnum* @param dbHost* @param dbName* @param username* @param pwd* @return*/public static String getDbRecoveryCmd(DatabaseTypeEnum databaseTypeEnum, String dbHost, String dbName, String username, String pwd, String sqlPath) {return switch (databaseTypeEnum) {case Mysql -> mysqlRecoveryCmd(dbHost, dbName, username, pwd, sqlPath);case KingBase -> kingBaseRecoveryCmd(dbHost, dbName, username, pwd, sqlPath);case Unknown -> null;};}/*** 获取数据的的备份命令** @param dbDriver* @param dbHost* @param dbName* @param username* @param pwd* @return*/public static String getDbRecoveryCmd(String dbDriver, String dbHost, String dbName, String username, String pwd, String sqlPath) {return getDbRecoveryCmd(getDbType(dbDriver), dbHost, dbName, username, pwd, sqlPath);}}
依赖枚举 DatabaseTypeEnum
public enum DatabaseTypeEnum {/*** mysql 数据库*/Mysql("mysql"),/*** 人大金仓数据*/KingBase("kingBase"),/*** 未知的数据库类型*/Unknown("unknown");private final String value;DatabaseTypeEnum(String value) {this.value = value;}
}
2、备份调用
参数获取@Value("${spring.datasource.driver-class-name}")
private String dbDriver;
@Value("${spring.datasource.url}")
private String dbUrl;
@Value("${spring.datasource.username}")
private String dbUsername;
@Value("${spring.datasource.password}")private String pwd;执行内容
String dbHost = dbUrl.split("//")[1].split(":")[0];String dbName = dbUrl.split("/")[3];// 去除问号及其后面的参数if (dbName.contains("?")) {dbName = dbName.split("\\?")[0];}String command = DatabaseUtil.getDbBackCmd(dbDriver, dbHost, dbName, dbUsername, pwd);log.info("数据备份命令:{}", command);// 创建进程构建器ProcessBuilder processBuilder = new ProcessBuilder();// window 用 cmd、linux 用 bashif (SystemUtil.getOsInfo().isWindows()) {processBuilder.command("cmd.exe", "/C", command); // 设置工作目录} else {processBuilder.command("/bin/bash", "-c", command); // 设置工作目录}// 启动进程Process process = processBuilder.start();InputStream errorStream = process.getErrorStream();InputStreamReader isr = new InputStreamReader(errorStream, "GBK");BufferedReader br = new BufferedReader(isr);String line;while ((line = br.readLine()) != null) {log.info(line);}br.close();isr.close();errorStream.close();if (process.waitFor() != 0) {log.error("数据备份失败");throw new Exception("备份失败");}
3、数据库恢复调用
恢复失败了,数据sql 脚本被执行,但是恢复失败了
String dbHost = dbUrl.split("//")[1].split(":")[0];String dbName = dbUrl.split("/")[3];// 去除问号及其后面的参数if (dbName.contains("?")) {dbName = dbName.split("\\?")[0];}assert file != null;String command = DatabaseUtil.getDbRecoveryCmd(dbDriver, dbHost, dbName, dbUsername, pwd, file.getAbsolutePath());// 创建进程构建器ProcessBuilder processBuilder = new ProcessBuilder();// window 用 cmd、linux 用 bashif (SystemUtil.getOsInfo().isWindows()) {processBuilder.command("cmd.exe", "/C", command); // 设置工作目录} else {processBuilder.command("/bin/bash", "-c", command); // 设置工作目录}// 启动进程Process process = processBuilder.start();InputStream errorStream = process.getErrorStream();InputStreamReader isr = new InputStreamReader(errorStream, StandardCharsets.UTF_8);BufferedReader br = new BufferedReader(isr);String line;while ((line = br.readLine()) != null) {log.info(line);}br.close();isr.close();errorStream.close();if (process.waitFor() != 0) {return CommonResult.fail("数据恢复失败");}
二、导出dmp版(推荐)
1、工具类-导出 dmp
1)DatabaseUtil 工具类
package com.fisec.common.util;import cn.hutool.core.util.StrUtil;
import cn.hutool.system.SystemUtil;
import com.fisec.common.enums.DatabaseTypeEnum;import java.util.HashMap;public class DatabaseUtil {/*** 根据数据库驱动类型,获取数据库类型** @param dbDriver* @return*/public static DatabaseTypeEnum getDbType(String dbDriver) {if (dbDriver.startsWith("com.mysql")) {return DatabaseTypeEnum.Mysql;}if (dbDriver.startsWith("com.kingbase")) {return DatabaseTypeEnum.KingBase;}return DatabaseTypeEnum.Unknown;}/*** 获取备份文件的扩展名** @param dbDriver* @return*/public static String getFileExtension(String dbDriver) {if (dbDriver.startsWith("com.mysql")) {return ".sql";}if (dbDriver.startsWith("com.kingbase")) {return ".dmp";}return "";}/*** 获取mysql备份命令** @param dbHost* @param dbName* @param username* @param pwd* @return*/public static String mysqlBackLinuxCmd(String dbHost, String dbName, String username, String pwd, String saveSqlFile) {return String.format("mysqldump -h%s -u%s -p%s -R %s > %s", dbHost,username, pwd, dbName, saveSqlFile);}/*** 获取mysql备份命令* 切换磁盘需要添加,并奇幻盘符下命令执行** @param dbHost* @param dbName* @param username* @param pwd* @return*/public static String mysqlBackWindowsCmd(String dbHost, String dbName, String username, String pwd, String saveSqlFile) {return String.format("d: && cd D:/Program Files/MySQL/MySQL Server 8.0/bin && .\\mysqldump.exe -h%s -u%s -p%s -R %s > %s", dbHost,username, pwd, dbName, saveSqlFile);}/*** 获取 人大金仓数据备份命令** @param dbHost* @param dbName* @param username* @param pwd* @return*/public static String mysqlBackCmd(String dbHost, String dbName, String username, String pwd, String saveSqlFile) {if (SystemUtil.getOsInfo().isWindows()) {return mysqlBackWindowsCmd(dbHost, dbName, username, pwd, saveSqlFile);}return mysqlBackLinuxCmd(dbHost, dbName, username, pwd, saveSqlFile);}/*** 获取mysql备份命令** @param dbHost* @param dbName* @param username* @param pwd* @return*/public static String mysqlRecoveryWindowsCmd(String dbHost, String dbName, String username, String pwd, String sqlPath) {return String.format("d: && cd D:/Program Files/MySQL/MySQL Server 8.0/bin && .\\mysql.exe -h%s -u%s -p%s %s < %s", dbHost,username, pwd, dbName, sqlPath);}/*** 获取mysql备份命令** @param dbHost* @param dbName* @param username* @param pwd* @return*/public static String mysqlRecoveryLinuxCmd(String dbHost, String dbName, String username, String pwd, String sqlPath) {return String.format("mysql -h%s -u%s -p%s %s < %s", dbHost,username, pwd, dbName, sqlPath);}/*** 获取 人大金仓数据备份命令** @param dbHost* @param dbName* @param username* @param pwd* @return*/public static String mysqlRecoveryCmd(String dbHost, String dbName, String username, String pwd, String sqlPath) {if (SystemUtil.getOsInfo().isWindows()) {return mysqlRecoveryWindowsCmd(dbHost, dbName, username, pwd, sqlPath);}return mysqlRecoveryLinuxCmd(dbHost, dbName, username, pwd, sqlPath);}/*** 获取人大金仓的备份命令* 注:这里路径为 windows 默认路径 ,注版本为 V008R006C008B0014 路径需根据实际情况替换** @param dbHost* @param dbName* @param username* @param pwd* @return*/public static String kingBaseBackWindowsCmd(String dbHost, String dbName, String username, String pwd, String saveSqlFile) {return StrUtil.format("cd C:/Program Files/Kingbase/ES/V8/KESRealPro/V008R006C008B0014/ClientTools/bin && .\\exp.exe host={dbHost} port=54321 dbname={dbName} user={username} password={pwd} OWNER=public FILE={saveSqlFile}",new HashMap<>() {{put("dbHost", dbHost);put("dbName", dbName);put("username", username);put("pwd", pwd);put("saveSqlFile", saveSqlFile);}});}/*** 获取人大金仓的备份命令 - windows 默认路径 ,注版本为 V008R006C008B0014* 路径需根据实际情况替换* 所有 java 执行 linux命令需添加前缀 /bin/bash -c** @param dbHost* @param dbName* @param username* @param pwd* @return*/public static String kingBaseBackLinuxCmd(String dbHost, String dbName, String username, String pwd, String saveSqlFile) {return StrUtil.format("cd /opt/Kingbase/ES/V8/KESRealPro/V008R006C008B0014/ClientTools/bin && exp host={dbHost} port=54321 dbname={dbName} user={username} password={pwd} OWNER=public FILE={saveSqlFile}",new HashMap<>() {{put("dbHost", dbHost);put("dbName", dbName);put("username", username);put("pwd", pwd);put("saveSqlFile", saveSqlFile);}});}/*** 获取人大金仓的恢复数据库命令* 注:这里路径为 windows 默认路径 ,注版本为 V008R006C008B0014 路径需根据实际情况替换* CLEAN=y:imp程序先删掉数据库对象,再执行导入操作,默认值为n** @param dbHost* @param dbName* @param username* @param pwd* @return*/public static String kingBaseRecoveryWindowsCmd(String dbHost, String dbName, String username, String pwd, String sqlPath) {return StrUtil.format("cd C:/Program Files/Kingbase/ES/V8/KESRealPro/V008R006C008B0014/ClientTools/bin && .\\imp.exe host={dbHost} port=54321 user={username} password={pwd} dbname={dbName} FROMUSER=public CLEAN=y FILE={sqlPath}",new HashMap<>() {{put("dbHost", dbHost);put("dbName", dbName);put("username", username);put("pwd", pwd);put("sqlPath", sqlPath);}});}/*** 获取人大金仓的备份命令 - windows 默认路径 ,注版本为 V008R006C008B0014* 路径需根据实际情况替换* 所有 java 执行 linux命令需添加前缀 /bin/bash -c** @param dbHost* @param dbName* @param username* @param pwd* @return*/public static String kingBaseRecoveryLinuxCmd(String dbHost, String dbName, String username, String pwd, String sqlPath) {return StrUtil.format("cd /opt/Kingbase/ES/V8/KESRealPro/V008R006C008B0014/ClientTools/bin && imp host={dbHost} port=54321 user={username} password={pwd} dbname={dbName} FROMUSER=public CLEAN=y FILE={sqlPath}",new HashMap<>() {{put("dbHost", dbHost);put("dbName", dbName);put("username", username);put("pwd", pwd);put("sqlPath", sqlPath);}});}/*** 获取 人大金仓数据备份命令** @param dbHost* @param dbName* @param username* @param pwd* @return*/public static String kingBaseBackCmd(String dbHost, String dbName, String username, String pwd, String saveSqlFile) {if (SystemUtil.getOsInfo().isWindows()) {return kingBaseBackWindowsCmd(dbHost, dbName, username, pwd, saveSqlFile);}return kingBaseBackLinuxCmd(dbHost, dbName, username, pwd, saveSqlFile);}/*** 获取 人大金仓数据备份命令** @param dbHost* @param dbName* @param username* @param pwd* @return*/public static String kingBaseRecoveryCmd(String dbHost, String dbName, String username, String pwd, String sqlPath) {if (SystemUtil.getOsInfo().isWindows()) {return kingBaseRecoveryWindowsCmd(dbHost, dbName, username, pwd, sqlPath);}return kingBaseRecoveryLinuxCmd(dbHost, dbName, username, pwd, sqlPath);}/*** 根据数据类型 获取执行的命令** @param databaseTypeEnum* @param dbHost* @param dbName* @param username* @param pwd* @return*/public static String getDbBackCmd(DatabaseTypeEnum databaseTypeEnum, String dbHost, String dbName, String username, String pwd, String saveSqlFile) {return switch (databaseTypeEnum) {case Mysql -> mysqlBackCmd(dbHost, dbName, username, pwd, saveSqlFile);case KingBase -> kingBaseBackCmd(dbHost, dbName, username, pwd, saveSqlFile);case Unknown -> null;};}/*** 获取数据的的备份命令** @param dbDriver* @param dbHost* @param dbName* @param username* @param pwd* @return*/public static String getDbBackCmd(String dbDriver, String dbHost, String dbName, String username, String pwd, String saveSqlFile) {return getDbBackCmd(getDbType(dbDriver), dbHost, dbName, username, pwd,saveSqlFile);}/*** 根据数据类型 获取执行的命令** @param databaseTypeEnum* @param dbHost* @param dbName* @param username* @param pwd* @return*/public static String getDbRecoveryCmd(DatabaseTypeEnum databaseTypeEnum, String dbHost, String dbName, String username, String pwd, String sqlPath) {return switch (databaseTypeEnum) {case Mysql -> mysqlRecoveryCmd(dbHost, dbName, username, pwd, sqlPath);case KingBase -> kingBaseRecoveryCmd(dbHost, dbName, username, pwd, sqlPath);case Unknown -> null;};}/*** 获取数据的的备份命令** @param dbDriver* @param dbHost* @param dbName* @param username* @param pwd* @return*/public static String getDbRecoveryCmd(String dbDriver, String dbHost, String dbName, String username, String pwd, String sqlPath) {return getDbRecoveryCmd(getDbType(dbDriver), dbHost, dbName, username, pwd, sqlPath);}}
2、备份调用
// 1 备份的临时文件、清空,并创建备份的文件String sqlPath = uploadDir + File.separator + "sqlBack";FileUtil.del(sqlPath);String saveSqlName = fileName + DatabaseUtil.getFileExtension(dbDriver);String saveSqlFile = sqlPath + File.separator + saveSqlName;FileUtil.touch(saveSqlFile);// 3 获取备份命令,根据数据参数String dbHost = dbUrl.split("//")[1].split(":")[0];String dbName = dbUrl.split("/")[3];// 去除问号及其后面的参数if (dbName.contains("?")) {dbName = dbName.split("\\?")[0];}String command = DatabaseUtil.getDbBackCmd(dbDriver, dbHost, dbName, dbUsername, pwd, saveSqlFile);log.info("数据备份命令:{}", command);// 4 创建进程构建器,执行命令ProcessBuilder processBuilder = new ProcessBuilder();// window 用 cmd、linux 用 bashif (SystemUtil.getOsInfo().isWindows()) {processBuilder.command("cmd.exe", "/C", command); // 设置工作目录} else {processBuilder.command("/bin/bash", "-c", command); // 设置工作目录}// 5 启动进程Process process = processBuilder.start();// 6 打印输出InputStream errorStream = process.getErrorStream();InputStreamReader isr = new InputStreamReader(errorStream, "GBK");BufferedReader br = new BufferedReader(isr);String line;while ((line = br.readLine()) != null) {log.info(line);}br.close();isr.close();errorStream.close();if (process.waitFor() != 0) {log.error("数据备份失败");throw new Exception("备份失败");}
3、数据库恢复调用
String dbHost = dbUrl.split("//")[1].split(":")[0];String dbName = dbUrl.split("/")[3];// 去除问号及其后面的参数if (dbName.contains("?")) {dbName = dbName.split("\\?")[0];}assert file != null;String command = DatabaseUtil.getDbRecoveryCmd(dbDriver, dbHost, dbName, dbUsername, pwd, file.getAbsolutePath());// 创建进程构建器ProcessBuilder processBuilder = new ProcessBuilder();// window 用 cmd、linux 用 bashif (SystemUtil.getOsInfo().isWindows()) {processBuilder.command("cmd.exe", "/C", command); // 设置工作目录} else {processBuilder.command("/bin/bash", "-c", command); // 设置工作目录}// 启动进程Process process = processBuilder.start();log.info("还原执行命令:{}", command);// 获取子进程输出流、读取输出流内容BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));// 获取子进程输错误输出流、读取输出流内容BufferedReader errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));String line;while ((line = reader.readLine()) != null) {log.info(line);}String errorline;while ((errorline = errorReader.readLine()) != null) {log.warn(errorline);}if (process.waitFor() != 0) {return CommonResult.fail("数据恢复失败");}