最近項目中有一個這樣的需求,要求定時備份資料庫。看了一些網上的資料,了解到主要思路是是使用java中的Runtime類的exec()方法,可以直接調用windows的cmd指令,參數就是Mysql的備份指令。
一、Runtime類
首先說說這個神奇的Runtime類,主要封裝了Java程式的運作環境,每一個Java程式都有一個與之對應的Runtime執行個體,應用程式通過該對象與運作時環境相連,應用程式不能建立自己的Runtime執行個體,但可以通過getRuntime()方法獲得與之關聯的Runtime對象。
Runtime代表Java程式的運作時環境,可以通路JVM的相關資訊,如處理器數量,記憶體資訊。
1.1、常用API
addShutdownHook(Thread hook) 注冊新的虛拟機來關閉挂鈎。
availableProcessors()
向 Java 虛拟機傳回可用處理器的數目。
exec(String command) 在單獨的程序中執行指定的字元串指令。
exec(String[] cmdarray)
在單獨的程序中執行指定指令和變量。
exec(String[] cmdarray, String[] envp)
在指定環境的獨立程序中執行指定指令和變量。
exec(String[] cmdarray, String[] envp, File dir) 在指定環境和工作目錄的獨立程序中執行指定的指令和變量。
exec(String command, String[] envp) 在指定環境的單獨程序中執行指定的字元串指令。
exec(String command, String[] envp, File dir) 在有指定環境和工作目錄的獨立程序中執行指定的字元串指令。
exit(int status)
通過啟動虛拟機的關閉序列,終止目前正在運作的 Java 虛拟機。
freeMemory()
傳回 Java 虛拟機中的空閑記憶體量。
gc() 運作垃圾回收器。
InputStream getLocalizedInputStream(InputStream in) 已過時。 從 JDK 1.1 開始,将本地編碼位元組流轉換為 Unicode 字元流的首選方法是使用 InputStreamReader 和 BufferedReader 類。
OutputStream getLocalizedOutputStream(OutputStream out) 已過時。 從 JDK 1.1 開始,将 Unicode 字元流轉換為本地編碼位元組流的首選方法是使用 OutputStreamWriter、BufferedWriter 和 PrintWriter 類。
getRuntime() 傳回與目前 Java 應用程式相關的運作時對象。
halt(int status) 強行終止目前正在運作的 Java 虛拟機。
load(String filename) 加載作為動态庫的指定檔案名。
loadLibrary(String libname) 加載具有指定庫名的動态庫。
maxMemory() 傳回 Java 虛拟機試圖使用的最大記憶體量。
removeShutdownHook(Thread hook) 取消注冊某個先前已注冊的虛拟機關閉挂鈎。
runFinalization() 運作挂起 finalization 的所有對象的終止方法。
runFinalizersOnExit(value) 已過時。 此方法本身具有不安全性。它可能對正在使用的對象調用終結方法,而其他線程正在操作這些對象,進而導緻不正确的行為或死鎖。
totalMemory() 傳回 Java 虛拟機中的記憶體總量。
traceInstructions(on)
啟用/禁用指令跟蹤。
traceMethodCalls(on) 啟用/禁用方法調用跟蹤。
1.2、使用exec(String cmd)方法備份資料庫
DatabaseTool類
packagecom.china_amss.base.tools;importjava.io.BufferedReader;importjava.io.File;importjava.io.FileInputStream;importjava.io.FileOutputStream;importjava.io.IOException;importjava.io.InputStream;importjava.io.InputStreamReader;importjava.io.OutputStream;importjava.io.OutputStreamWriter;importcom.china_amss.base.thread.ErrorStreamThread;public classDatabaseTool {
public static voidbackup(String mysqlPath, String mysqlIp, String mysqlPort, String userName, String password, String database, String resultFile) {
InputStream in= null;
InputStreamReader isr= null;
BufferedReader br= null;
FileOutputStream fout= null;
OutputStreamWriter writer= null;try{
Runtime rt=Runtime.getRuntime();//調用mysql的安裝目錄的指令
Process process = rt.exec("\"" + mysqlPath + File.separator + "mysqldump\" --databases -h" + mysqlIp
+ " -P" +mysqlPort+ " -u" + userName + " -p" +password+ " --add-drop-database --default-character-set=utf8 "+ database + " --result-file="+resultFile);//設定導出編碼為utf-8。這裡必須是utf-8
in = process.getInputStream();//控制台的輸出資訊作為輸入流
ErrorStreamThread errStream = new ErrorStreamThread(process.getErrorStream()); //錯誤流另開線程,不然會阻塞
errStream.start();
}catch(Exception e) {
e.printStackTrace();
}finally{try{if(writer != null){
writer.close();
}if(fout != null){
fout.close();
}if(br != null){
br.close();
}if(isr != null){
isr.close();
}if(in != null){
in.close();
}
}catch(IOException e) {
e.printStackTrace();
}
}
}
ErrorStreamThread類:
packagecom.china_amss.base.thread;importjava.io.BufferedReader;importjava.io.IOException;importjava.io.InputStream;importjava.io.InputStreamReader;importcom.china_amss.ktms.exception.KTMSException;public class ErrorStreamThread extendsThread {private InputStream input; //控制台errorStream
publicErrorStreamThread(InputStream input) {this.input =input;
}
@Overridepublic voidrun() {
InputStreamReader isr= null;
BufferedReader buff= null;try{
isr= newInputStreamReader(input);
buff= newBufferedReader(isr);
String line;while ((line = buff.readLine()) != null) {if (line.indexOf("Warning") != 0) {throw newException(line);
}
}
}catch(Exception e) {throw new Exception("錯誤流線程方法異常", e);
}finally{try{if (buff != null) {
buff.close();
}if (isr != null) {
isr.close();
}
}catch(IOException e) {throw new Exception("錯誤流線程方法異常", e);
}
}
}
}
注意:此處因為要輸出錯誤提示,是以要使用另外一條線程輸出,不然會阻塞
注意:上面用到的指令參數可以去檢視我的另一篇專門整理了Mysql備份指令參數的文章,連結在這Mysql備份指令參數詳解