Java備份Oracle資料庫
Java線程、Process、ProcessBuilder
2010 年 6 月 20 日
文章內容描述了使用Java執行外部Oracle匯出命令備份資料庫功能的樣本,依據此例子進行修改製造一些bug,然後將會對Java外部命令這塊會有一個更加清晰的認知(個人觀點僅供參考,不許拍磚,哈)
小細節
-
·試著把innerTh.start()這段給注釋掉,然後再把使用者名稱或密碼寫錯。
-
·有些程式是不會在命令列有輸出的,比如最直接的plsqldev.exe、MindManager.exe
-
·試著把將要執行的命令改成我們本地相關.exe程式,如上面所例或乾脆TM.exe試試。
程式碼範例:
| package org.ybygjy.basic.oracle;</p><p>import java.io.File;<br />import java.io.FileOutputStream;<br />import java.io.IOException;<br />import java.io.InputStream;<br />import java.nio.ByteBuffer;<br />import java.nio.channels.Channels;<br />import java.nio.channels.FileChannel;<br />import java.nio.channels.ReadableByteChannel;<br />import java.util.ArrayList;<br />import java.util.List;<br />import java.util.Map;</p><p>/**<br /> * java外部系統命令模式備份資料庫<br /> * @author WangYanCheng<br /> * @version 2010-6-19<br /> */<br />public class BackupOracleDatabase {<br /> /**<br /> * 封裝執行入口<br /> */<br /> public void doWork() {<br /> InnerClass innerInst =<br /> new InnerClass("DB_USER", "DB_PASS", "127.0.0.1:1521/ORCL", "E:/dbback/BACK201006.DMP");<br /> Thread thInst = new Thread(innerInst);<br /> thInst.start();<br /> }</p><p> /**<br /> * 用於分擔執行命令<br /> * @author WangYanCheng<br /> * @version 2010-6-19<br /> */<br /> class InnerClass implements Runnable {<br /> /** 使用者名稱 */<br /> private String userName;<br /> /** 密碼 */<br /> private String userPass;<br /> /** 服務地址 */<br /> private String serverAddr;<br /> /** 輸出檔案路徑 */<br /> private String outFilePath;</p><p> /**<br /> * constructor<br /> * @param userName userName<br /> * @param userPass userPass<br /> * @param serverAddr 服務地址必須帶<strong>連接埠</strong>/<strong>SID</strong><br /> * @param outFilePath outPath<br /> */<br /> public InnerClass(String userName, String userPass, String serverAddr, String outFilePath) {<br /> this.userName = userName;<br /> this.userPass = userPass;<br /> this.serverAddr = serverAddr;<br /> this.outFilePath = outFilePath;<br /> }</p><p> /**<br /> * 提供執行的命令串<br /> * @return commStr 命令串<br /> */<br /> private List doBuildCommand() {<br /> List rtnList = new ArrayList();<br /> rtnList.add("EXP");<br /> rtnList.add("@USER@/@PASSWORD@@@SERVER@".replaceAll("@USER@", this.userName)<br /> .replaceAll("@PASSWORD@", this.userPass).replaceAll("@SERVER@", this.serverAddr));<br /> rtnList.add("FILE=/"@FILE@/"".replaceAll("@FILE@", this.outFilePath));<br /> rtnList.add("TABLES=(SY_TABLE_DEF)");<br /> return rtnList;<br /> }<br /> /**<br /> * 構建ProcessBuilder執行個體<br /> * @param workDir 當前進程工作目錄<br /> * @return pbInst ProcessBuilder執行個體<br /> * @see ProcessBuilder<br /> */<br /> private ProcessBuilder buildProcessBuilder(File workDir) {<br /> new ProcessBuilder();<br /> List commandArray = (doBuildCommand());<br /> ProcessBuilder pbInst = new ProcessBuilder(commandArray);<br /> pbInst.command(commandArray);<br /> Map envMap = pbInst.environment();<br /> envMap.clear();<br /> envMap.putAll(System.getenv());<br /> pbInst.directory(workDir);<br /> pbInst.redirectErrorStream(true);<br /> return pbInst;<br /> }<br /> /**<br /> * 線程執行入口<br /> */<br /> public void run() {<br /> File tmpOutFile = new File(this.outFilePath);<br /> File outDir = tmpOutFile.getParentFile();<br /> ProcessBuilder pbInst = buildProcessBuilder(outDir);<br /> try {<br /> Process proInst = pbInst.start();<br /> final InputStream ins = proInst.getInputStream();<br /> File outFile = new File(outDir, "exp.log");<br /> outFile.createNewFile();<br /> final FileChannel focInst = new FileOutputStream(outFile).getChannel();<br /> Thread innerTh = new Thread() {<br /> ByteBuffer byteBuffer = ByteBuffer.allocate(1024);<br /> public void run() {<br /> ReadableByteChannel rbcObj = Channels.newChannel(ins);<br /> try {<br /> while (rbcObj.read(byteBuffer) != -1) {<br /> byteBuffer.flip();<br /> focInst.write(byteBuffer);<br /> byteBuffer.clear();<br /> }<br /> } catch (IOException ioe) {<br /> ioe.printStackTrace();<br /> }<br /> }<br /> };<br /> // innerTh.setDaemon(true);<br /> innerTh.start();<br /> } catch (IOException ioe) {<br /> ioe.printStackTrace();<br /> }<br /> }<br /> }</p><p> /**<br /> * 測試入口<br /> * @param args 參數列表<br /> */<br /> public static void main(String[] args) {<br /> new BackupOracleDatabase().doWork();<br /> }<br />}<br /> |