1.最近在做一个基于j2ee的web项目,这个项目web服务器和数据库都部署在linux服务器上,其中我要实现数据库的备份和恢复功能,实际上就是java调用expdp/impdp,这个想想其实应该蛮简单的,runtime.getruntime.exec(),大概就是这个么回事,但是实际在使用中,发现
InputStream istr1 = process.getInputStream(); BufferedReader br1 = new BufferedReader(new InputStreamReader(istr1)); String str1; while ((str1=br1.readLine()) != null) { System.out.println(str1 + "\n"); }
会发生阻塞,实际上如果不加这个得到输入流反倒是可以运行成功,后来经过网上搜索,发现oracle设计的比较怪,他不是采用inputstream输出信息,而是errorstream输出信息,所以会造成inputsteam的阻塞,解决也很简单
InputStream istr = process.getErrorStream();
BufferedReader br = new BufferedReader(new InputStreamReader(istr));
String str;
while ((str=br.readLine()) != null)
{ System.out.println(str + "\n");
if(str.indexOf("错误")!=-1){
process.destroy();
System.out.println("backup failure");
return 0;
}
}
process.waitFor();
}
实际上的目的就只是为了检测oracle的备份是否执行完毕。
2.第二个技术问题,如果你直接采用exec(expdp)在windows下是没有问题的。但是在linux下会抛出异常,cannot run program,所以要采用比较麻烦点的方法,实质上expdp,impdp在linux下都是sh文件,
所以如下:
String EXPStr="expdp ?/?@? directory=dump_dir dumpfile=? CONTENT=ALL logfile=exp.log "; EXPStr=EXPStr.replaceFirst("\\?", user); EXPStr=EXPStr.replaceFirst("\\?", pass); EXPStr=EXPStr.replaceFirst("\\?", DBname); EXPStr=EXPStr.replaceFirst("\\?", getDBDumpName(DBname)); process = Runtime.getRuntime().exec(new String[] { "sh", "-c", EXPStr});
实质就是new String[] { "sh", "-c", EXPStr});,
3.另外如果你配置的文件良好,就是oracle配置的路径什么很好,那么应该就可以直接运行了,我们这边oracle赔的一团糟,所以我额外还要运行
process = Runtime.getRuntime().exec( new String[] { "sh", "-c", "source /etc/profile"});
这个etc/profile里面实际上包括了所有的oracle export,这样