扣扣技术分享交流群:1125844267
因为有大量的文件需要复制,又要求时效性,所以尝试用java执行Linux复制命令。部分代码是直接网上拿过来的,具体出处忘记了,所以没法给出链接!直接上代码。。。
public int copyFile(String sourceDirectory, String distributeProductPath){
//根据api,其实exec方法可以直接执行命令,但是推荐用数组。
//因为如果一些命令中包含特殊符号,命令会失效。经过测试如果直接执行复制命令,
//目录可以复制过来,但是目录下的文件会丢失
String[] commands = new String[3];
commands[0] = new String("/bin/sh");
commands[1] = new String("-c");
//cp --parents /xian/GC/A/B/* /zi/newLocation
//--parents才会将整个目录都复制过去,否则只复制最终的文件
//用parents参数的目的就是为了将源端的文件连同文件所在的目录一同复制过来
commands[2] = new String("cp --parents "+ sourceDirectory + " " + distributeProductPath);
Runtime rt = Runtime.getRuntime();
Process proc = null;
try {
proc = rt.exec(commands);
} catch (IOException e) {
logger.error("执行Linux复制命令出错:{}",e);
return -1;
}
//exec执行Linux命令其实会在系统环境下启动一个子进程
//外部程序的输出流、错误流会输入到虚拟机进程中,而默认的缓冲区大小有限,
//当输出、错误打印量较大时,会阻塞进程的执行,虚拟机也可能会死锁。
//看文档找资料并没有找到很好的处理方式,目前只能这样处理
StreamRedirector errors = new StreamRedirector(proc.getErrorStream());
StreamRedirector outputs = new StreamRedirector(proc.getInputStream());
errors.start();
outputs.start();
int exitVal = -1; //如果返回的exitVal为0,则为进程正确结束,从而判断复制是否成功
try {
exitVal = proc.waitFor();
} catch (InterruptedException e) {
logger.error("执行命令的子进程没有正确结束:{}",e);
}
return exitVal;
}
像Runtime、Process具体方法可以去看jdk文档,Java 8 中文版 - 在线API中文手册 - 码工具,直接搜索关键字就可以
/**
* 线程单独处理输入流
*/
class StreamRedirector extends Thread{
InputStream is;
StreamRedirector(InputStream is) {
this.is = is;
}
public void run() {
InputStreamReader isr = null;
BufferedReader br = null;
try {
isr = new InputStreamReader(is);
br = new BufferedReader(isr);
String line = null;
while ((line = br.readLine()) != null){
System.out.println(line);
logger.info("执行命令线程返回的结果:"+line);
}
} catch (Exception e) {
e.printStackTrace();
}finally {
if(br != null){
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(isr != null){
try {
isr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
个人建的交流群1125844267,欢迎大家加入!
如果内容对大家有所帮助,感谢鼓励!实现我小时候一人给我一块钱的美梦,哈哈!