public class ProcessBuilder {
/**
* 进程运行标记文件名称
*/
public final String SIGN_RUN_FILE_NAME = "run.do";
private static Logger log = Logger.getLogger(ProcessBuilder.class);
/**
* 创建进程
*
* @param cmd
* 命令行
* @param workDir
* 指定的工作目录
* @throws IOException
*/
public Process create(String[] cmd, File dir) throws Exception {
// 执行命令行,创建新的进程
Process ps = Runtime.getRuntime().exec(cmd, null, dir);
if (ps != null) {
// (非常重要)输出进程流中的信息,防止运行过程中因为进程流的阻塞,导致被迫挂起
new ProcessStreamUtil(ps.getErrorStream(), "ERROR").start();
new ProcessStreamUtil(ps.getInputStream(), "OUTPUT").start();
return ps;
}
return null;
}
/**
* 标记进程的运行 (注:在运行主目录下创建一个目标文件,并加上文件锁, 用于当外部程通过文件锁来判断程序是否正在运行)
*
* @return
*/
public boolean signRunning() throws Exception {
// 运行目录
String lockPath = System.getProperty("user.dir");
File dir = new File(lockPath);
if (!dir.exists()) {
dir.mkdirs();
}
// 待锁定的目标文件路径
lockPath = lockPath + File.separator + SIGN_RUN_FILE_NAME;
log.debug("标记文件:" + lockPath);
return this.tryLockFile(lockPath);
}
/**
* 通过文件锁来判断程序是否正在运行
*
* @return 如果正在运行返回true,否则返回false
*/
public boolean isRunning(String lockFilePath) throws Exception {
log.debug("嗅探文件:" + lockFilePath);
int i = 0;
// 延时60秒,嗅探目标文件是否已被锁上
do {
if (i++ > 20) {
return false;
}
if (!this.tryLockFile(lockFilePath)) {
return true;
} else {
Thread.sleep(3 * 1000L);
}
} while (true);
}
/**
* 尝试对目标文件进行加锁操作
*
* @param lockFilePath
* 目标文件
* @return
*/
private boolean tryLockFile(String lockFilePath) throws Exception {
// 待锁定的目标文件路径
log.debug(lockFilePath);
RandomAccessFile fis = null;
FileLock flock = null;
FileChannel lockfc = null;
try {
fis = new RandomAccessFile(lockFilePath, "rw");
lockfc = fis.getChannel();
// 尝试加锁
flock = lockfc.tryLock();
if (flock != null) {
return true;
}
} finally {
// 释放资源
if (fis != null)
fis.close();
if (flock != null)
lockfc.close();
}
return false;
}
}
// 进程流输出工具类
public class ProcessStreamUtil extends Thread {
private Logger log = Logger.getLogger(ProcessStreamUtil.class);
private InputStream is = null;
private String type = null;
public ProcessStreamUtil(InputStream is, String type) {
this.is = is;
this.type = type;
}
public void run() {
log.debug(type + "......");
InputStreamReader isr = null;
BufferedReader br = null;
try {
isr = new InputStreamReader(is);
br = new BufferedReader(isr);
String line = null;
while ((line = br.readLine()) != null) {
log.debug(type + ">" + line);
}
} catch (Exception ioe) {
log.error(ioe);
} finally {
try {
if (isr != null)
isr.close();
if (br != null)
br.close();
} catch (Exception er) {
log.error(er);
}
}
}
}