一眼看過去相信大家都知道用Runtime.getRuntime().exec來調(diào)用,我的需求就是:
調(diào)用Oracle EXP命令完成備份,并返回生成的備份文件名,這個(gè)備份文件會(huì)很快在其他的地方被使用。
采用Runtime.getRuntime().exec我們都知道,需要處理它的InputStream,以避免出現(xiàn)執(zhí)行的命令輸出的信息過多使得進(jìn)程被堵死,OK,按照這樣的方法,開寫:
String[] cmds = new String[ 3 ];
cmds[ 0 ] = " cmd " ;
cmds[ 1 ] = " /C " ;
cmds[ 2 ] = "exp username/password@sid file=xxx.dmp log=xxx.log";
Process process = Runtime.getRuntime().exec(cmds);
try {
InputStreamReader isr = new InputStreamReader(process.getInputStream());
BufferedReader br = new BufferedReader(isr);
String line = null ;
while ((line = br.readLine()) != null ) {
System.out.println(line);
}
}
catch (IOException ioe) {
ioe.printStackTrace();
} 寫完收工,執(zhí)行,傻了,進(jìn)程被掛S了,到底什么原因呢,開始瞎嘗試,把讀取process的InputStream的部分全部去掉,執(zhí)行,竟然OK,更暈,但這個(gè)時(shí)候出現(xiàn)了一個(gè)問題,那就是沒法知道什么時(shí)候備份文件完全生成了,如果在Runtime.getRuntime后去獲取備份文件,那個(gè)時(shí)候甚至連備份文件都沒生成,之后甚至嘗試過輪詢直到備份文件生成,再往下走,那樣還是有問題,就是生成的那個(gè)備份文件永遠(yuǎn)都只有正常的一半的大小,只有在整個(gè)進(jìn)程退出的時(shí)候它才正常的全部生成。
竟然碰到這樣的問題,徹底暈,開始google,竟然只查到一篇和我這同樣的問題,更郁悶的是那個(gè)帖子最后樓主寫了一句“問題解決了”,但沒寫是怎么解決的,郁悶S。
只好自己開始嘗試各種辦法,上網(wǎng)抓人到處問,最后在自己不斷的嘗試下終于是出現(xiàn)了轉(zhuǎn)機(jī),在我的N+1次嘗試的時(shí)候我改為只讀取process的ErrorStream,然后執(zhí)行,暈,OK了,在導(dǎo)出成功的情況下沒有問題,但在導(dǎo)出有錯(cuò)誤的時(shí)候(像sid不對(duì),用戶名錯(cuò)誤,數(shù)據(jù)庫沒啟動(dòng)等)進(jìn)程還是被掛S,但只要導(dǎo)出成功沒問題,導(dǎo)出有錯(cuò)誤的問題是很好處理的,OK,最后試驗(yàn)的代碼改為這樣:
String[] cmds = new String[3];
cmds[0] = "cmd";
cmds[1] = "/C";
cmds[2]=commandBuf.toString();
Process process=Runtime.getRuntime().exec(cmds);
boolean shouldClose=false;
try {
InputStreamReader isr = new InputStreamReader(process.getErrorStream());
BufferedReader br = new BufferedReader(isr);
String line = null;
while ((line = br.readLine()) != null){
if(line.indexOf("錯(cuò)誤")!=-1){
shouldClose=true;
break;
}
}
}
catch (IOException ioe) {
shouldClose=true;
}
if(shouldClose)
process.destroy();
int exitVal = process.waitFor(); 當(dāng)然,實(shí)際的代碼中不能像這里寫的一樣,直接去判斷是否含錯(cuò)誤這個(gè)字符串,而且這段代碼是只適合在winnt版本以上的windows操作系統(tǒng)上執(zhí)行的。
這樣反而可以了,說明什么呢,說明在執(zhí)行oracle的exp時(shí),出現(xiàn)了一個(gè)很怪的現(xiàn)象,就是exp在console輸出的信息沒有被放入InputStream,反而是放到了ErrorStream中(即使正確的情況也是),這就導(dǎo)致了按照正常的情況去寫這段代碼的話反而會(huì)出問題。
擔(dān)心以后再次碰到這樣的問題,備忘一下....