在我们的项目开发中,有时候为了提高性能,需要调用其他的工具来执行任务。举例来说,当数据库数据量增长比较快的时候,我们需要定期dump数据。而对于大数据量的数据的dump来说,dump时间是需要控制在某个量级的。这个时候,我们不能通过java来生成insert语句这种方式来dump数据的,因为它执行效率很低,而且BLOB、CLOB字段没法处理。相信dba都知道,oracle的dump是可以通过oracle client提供的exp命令来生成的,这种方式效率快,且大字段数据可以直接处理。
今天,我就讲一下怎么通过java命令来调用第三方软件的cmd命令或者shell脚本。
首先,我们建一个用来演示的cmd脚本testCmd.cmd,内容如下:
echo "hello!"
ipconfig
netstat -ans > netstat.txt
然后,就可以通过Runtime.getRuntime().exec来执行这个脚本了,代码如下:
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
public class TestCmd {
public static void main(String[] args) throws Exception {
Process process = Runtime.getRuntime().exec("D:/testCmd/testCmd.cmd", null, new File("D:/testCmd"));
// 等待调用的命令执行完,可用来统计时间或控制程序同步执行
process.waitFor();
// 打印命令的输出信息
printCmdOutMsg(process.getInputStream());
// 打印命令的错误信息
printCmdOutMsg(process.getErrorStream());
}
static void printCmdOutMsg(InputStream is) throws IOException {
System.out.println("----------------start----------------------");
BufferedReader reader = new BufferedReader(new InputStreamReader(is, Charset.forName("gbk")));
String out = reader.readLine();
while (out != null) {
System.out.println(out);
out = reader.readLine();
}
System.out.println("----------------end----------------------");
}
}
从上面的代码中可以看到,我们是通过Runtime.getRuntime().exec来调用cmd脚本,进而达到调用第三方工具的目的。实现方法很简单,下面说一下需要注意的几点:
1.Runtime.getRuntime().exec方法是一个异步调用的过程,调用完命令后,它会立即返回;
2.如果需要等待命令执行完再往后面执行,例如统计执行时间,则需要调用process.waitFor()来阻塞这个线程;
3.我们可以通过process.getInputStream()来获取调用命令的输出流,也可以通过process.getErrorStream()获取错误信息流,这些可以用来分析命令运行结果;
4.Runtime.exec(String command, String[] envp, File dir)第三个参数可以指定命令在哪个目录执行
5.Runtime.exec执行的可以是命令,也可以是批处理脚本。但是,这些命令要么配在PATH路径下,要么指定命令绝对路径