最近在java代碼中使用runtime.exec執(zhí)行rsync命令做同步,發(fā)現(xiàn)當(dāng)兩個(gè)目錄需要非常大同步工作的時(shí)候,rsync進(jìn)程就會(huì)一直阻塞。查看了jdk幫助,以及google都無果,于是打算把執(zhí)行的信息都log出來,結(jié)果執(zhí)行突然成功。仔細(xì)思考,這個(gè)問題應(yīng)該是進(jìn)程執(zhí)行命令的時(shí)候,輸出結(jié)果有個(gè)buffer,如果buffer已經(jīng)滿了,而沒有進(jìn)程去讀,這個(gè)進(jìn)程就會(huì)阻塞等待,導(dǎo)致我前面的問題出現(xiàn)。
效果可以通過如下代碼說明:
- import java.io.*;
-
- public class Rsync{
- public static void main(String[] args) throws Exception{
- if(args.length != 2){
- System.out.println("Usage: java Rsync src des");
- return;
- }
- Process proc = Runtime.getRuntime().exec("rsync -v -r -e --progress ssh -t -C " + args[0] + " " + args[1]);
- System.out.println("Waiting for end...");
- BufferedReader br = new BufferedReader(new InputStreamReader(proc.getInputStream()));
- String line = null;
- while((line = br.readLine()) != null){
- System.out.println(line);
- }
- br.close();
- int exitValue = 0;
- if((exitValue = proc.waitFor()) != 0){
- System.out.println("exitValue:" + exitValue);
- }
- System.out.println("rsync complete!");
- }
- }
import java.io.*;public class Rsync{public static void main(String[] args) throws Exception{if(args.length != 2){System.out.println("Usage: java Rsync src des");return;}Process proc = Runtime.getRuntime().exec("rsync -v -r -e --progress ssh -t -C " + args[0] + " " + args[1]);System.out.println("Waiting for end...");BufferedReader br = new BufferedReader(new InputStreamReader(proc.getInputStream()));String line = null;while((line = br.readLine()) != null){System.out.println(line);}br.close();int exitValue = 0;if((exitValue = proc.waitFor()) != 0){System.out.println("exitValue:" + exitValue);}System.out.println("rsync complete!");}}
如果注釋掉:
- BufferedReader br = new BufferedReader(new InputStreamReader(proc.getInputStream()));
- String line = null;
- while((line = br.readLine()) != null){
- System.out.println(line);
- }
- br.close();
BufferedReader br = new BufferedReader(new InputStreamReader(proc.getInputStream()));String line = null;while((line = br.readLine()) != null){System.out.println(line);}br.close();
在兩個(gè)目錄需要大量的同步操作時(shí)就會(huì)一直blocked住。
所以如果你不需要執(zhí)行命令的輸出,最好直接將輸出重定向到 > /dev/nll