最近在java代码中使用runtime.exec执行rsync命令做同步,发现当两个目录需要非常大同步工作的时候,rsync进程就
会一直阻塞。查看了jdk帮助,以及google都无果,于是打算把执行的信息都log出来,结果执行突然成功。仔细思考,这个问题应该是进程执行命令的
时候,输出结果有个buffer,如果buffer已经满了,而没有进程去读,这个进程就会阻塞等待,导致我前面的问题出现。
效果可以通过如下代码说明:
- 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();
在两个目录需要大量的同步操作时就会一直blocked住。
所以如果你不需要执行命令的输出,最好直接将输出重定向到 > /dev/nll