<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Swing


    天行健 君子以自強(qiáng)不息

    posts - 69, comments - 215, trackbacks - 0, articles - 16
       :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

    java調(diào)用Oracle EXP備忘

    Posted on 2007-05-18 09:31 zht 閱讀(450) 評(píng)論(0)  編輯  收藏 所屬分類(lèi): J2se

    一眼看過(guò)去相信大家都知道用Runtime.getRuntime().exec來(lái)調(diào)用,我的需求就是:
    調(diào)用Oracle EXP命令完成備份,并返回生成的備份文件名,這個(gè)備份文件會(huì)很快在其他的地方被使用。
    采用Runtime.getRuntime().exec我們都知道,需要處理它的InputStream,以避免出現(xiàn)執(zhí)行的命令輸出的信息過(guò)多使得進(jìn)程被堵死,OK,按照這樣的方法,開(kāi)寫(xiě):

    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();

            }
    寫(xiě)完收工,執(zhí)行,傻了,進(jìn)程被掛S了,到底什么原因呢,開(kāi)始瞎嘗試,把讀取process的InputStream的部分全部去掉,執(zhí)行,竟然OK,更暈,但這個(gè)時(shí)候出現(xiàn)了一個(gè)問(wèn)題,那就是沒(méi)法知道什么時(shí)候備份文件完全生成了,如果在Runtime.getRuntime后去獲取備份文件,那個(gè)時(shí)候甚至連備份文件都沒(méi)生成,之后甚至嘗試過(guò)輪詢(xún)直到備份文件生成,再往下走,那樣還是有問(wèn)題,就是生成的那個(gè)備份文件永遠(yuǎn)都只有正常的一半的大小,只有在整個(gè)進(jìn)程退出的時(shí)候它才正常的全部生成。
    竟然碰到這樣的問(wèn)題,徹底暈,開(kāi)始google,竟然只查到一篇和我這同樣的問(wèn)題,更郁悶的是那個(gè)帖子最后樓主寫(xiě)了一句“問(wèn)題解決了”,但沒(méi)寫(xiě)是怎么解決的,郁悶S。
    只好自己開(kāi)始嘗試各種辦法,上網(wǎng)抓人到處問(wèn),最后在自己不斷的嘗試下終于是出現(xiàn)了轉(zhuǎn)機(jī),在我的N+1次嘗試的時(shí)候我改為只讀取process的ErrorStream,然后執(zhí)行,暈,OK了,在導(dǎo)出成功的情況下沒(méi)有問(wèn)題,但在導(dǎo)出有錯(cuò)誤的時(shí)候(像sid不對(duì),用戶(hù)名錯(cuò)誤,數(shù)據(jù)庫(kù)沒(méi)啟動(dòng)等)進(jìn)程還是被掛S,但只要導(dǎo)出成功沒(méi)問(wèn)題,導(dǎo)出有錯(cuò)誤的問(wèn)題是很好處理的,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í)際的代碼中不能像這里寫(xiě)的一樣,直接去判斷是否含錯(cuò)誤這個(gè)字符串,而且這段代碼是只適合在winnt版本以上的windows操作系統(tǒng)上執(zhí)行的。
    這樣反而可以了,說(shuō)明什么呢,說(shuō)明在執(zhí)行oracle的exp時(shí),出現(xiàn)了一個(gè)很怪的現(xiàn)象,就是exp在console輸出的信息沒(méi)有被放入InputStream,反而是放到了ErrorStream中(即使正確的情況也是),這就導(dǎo)致了按照正常的情況去寫(xiě)這段代碼的話反而會(huì)出問(wèn)題。

    擔(dān)心以后再次碰到這樣的問(wèn)題,備忘一下....
    posted on 2006-11-22 22:43 BlueDavy 閱讀(1593) 評(píng)論(5)  編輯 收藏 引用 所屬分類(lèi): Java

    評(píng)論

    # re: java調(diào)用Oracle EXP備忘 2006-11-23 13:09 javabeginer
    從沒(méi)寫(xiě)過(guò)有關(guān)process的東西,學(xué)習(xí)!  回復(fù)  更多評(píng)論
      

    # re: java調(diào)用Oracle EXP備忘 2006-11-24 14:38 kruce[匿名]
    正如你所說(shuō)的,處理Process的時(shí)候要注意及時(shí)讀取子進(jìn)程的輸出流,不然可能導(dǎo)致子進(jìn)程堵塞,甚至死鎖。
    如果我是你,我會(huì)這么來(lái)排除bug。
    1,把對(duì)InputStream的處理放到一個(gè)單獨(dú)Thread里面。
    2,用ProcessBuilder的redirectErrorStream來(lái)合并OutputStream和ErrorStream。注意子進(jìn)程的InputStream對(duì)應(yīng)父進(jìn)程的OutStream。如果不合并這兩個(gè)流的話則必須并行排空它們,順序的排空會(huì)導(dǎo)致思索。
    建議你好好看看5.0的API和JLS。  回復(fù)  更多評(píng)論
      

    # re: java調(diào)用Oracle EXP備忘 2006-11-24 21:34 BlueDavy
    @kruce[匿名]
    ....我用的是1.4....雖然我也很想用5.0的ProcessBuilder  回復(fù)  更多評(píng)論
      

    # re: java調(diào)用Oracle EXP備忘 2007-01-11 16:41 roygbip
    我也遇到你這樣的問(wèn)題,不過(guò)我還是用getInputStream()才可以,用getErrorStream我也試了一下,只能倒入300條數(shù)據(jù)就卡住了.  回復(fù)  更多評(píng)論
    主站蜘蛛池模板: 亚洲AV无码专区亚洲AV伊甸园| 亚洲国产电影av在线网址| 亚洲无码一区二区三区| 四虎影视免费永久在线观看| 一级一黄在线观看视频免费| 无码乱人伦一区二区亚洲一| 成年女人免费v片| 亚洲成AV人片在WWW| 亚洲人成伊人成综合网久久久 | 亚洲成在人线aⅴ免费毛片| 伊在人亚洲香蕉精品区麻豆| 毛片在线全部免费观看| 亚洲免费一级视频| 亚洲色偷拍区另类无码专区| 4虎永免费最新永久免费地址| 在线播放亚洲精品| 亚洲精品福利网泷泽萝拉| 四虎永久成人免费影院域名| 91在线老王精品免费播放| 国产亚洲精品成人久久网站| 亚洲精品动漫在线| 亚洲欧洲∨国产一区二区三区 | 国产精品无码一二区免费| 免费观看91视频| 一级片在线免费看| 亚洲影视自拍揄拍愉拍| 国产AV无码专区亚洲Av| 国产伦精品一区二区三区免费迷| 91精品国产免费入口| 国产美女视频免费观看的网站| 亚洲kkk4444在线观看| 亚洲黄色一级毛片| 在线播放亚洲第一字幕| 日韩一品在线播放视频一品免费| 99视频在线看观免费| caoporm碰最新免费公开视频| 亚洲男人的天堂网站| 亚洲伊人久久大香线蕉| 久久丫精品国产亚洲av不卡| 亚洲人成亚洲人成在线观看| 免费又黄又爽又猛的毛片|