最新改变:解决执行exe输出太多,线程阻塞。改用线程读取输出流
package org.jeecg.modules.dam.util;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.vo.Result;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;
@Slf4j
public class ExecuteCmdUtils {
public static Boolean OVER_FLAG = false;
/**
* 执行cmd命令
* @param command 命令
* @param overFlag 结束标志
*/
public static Result<?> executeCmd(String command,String overFlag){
Runtime runtime = Runtime.getRuntime();
Process process = null;
try {
process = runtime.exec(command);
} catch (IOException e) {
e.printStackTrace();
}
try {
//获取进程的标准输入流
final InputStream is1 = process.getInputStream();
//获取进城的错误流
final InputStream is2 = process.getErrorStream();
//启动两个线程,一个线程负责读标准输出流,另一个负责读标准错误流
if(overFlag!=null) {
new Thread() {
public void run() {
BufferedReader br1 = null;
try {
br1 = new BufferedReader(new InputStreamReader(is1, "GBK"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
try {
String line1 = null;
while ((line1 = br1.readLine()) != null) {
if (line1 != null){}
System.out.println(line1);
if (!"".equals(line1) && line1.contains(overFlag)) {//计算完成标志
System.out.println("计算成功结束标志!!!");
OVER_FLAG = !OVER_FLAG;//重置
interrupt();
break;
}
}
} catch (IOException e) {
e.printStackTrace();
}
finally{
try {
is1.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}.start();
}else{
new Thread() {
public void run() {
BufferedReader br1 = null;
try {
br1 = new BufferedReader(new InputStreamReader(is1, "GBK"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
try {
String line1 = null;
while ((line1 = br1.readLine()) != null) {
if (line1 != null){}
System.out.println(line1);
}
} catch (IOException e) {
e.printStackTrace();
}
finally{
try {
is1.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}.start();
}
new Thread() {
public void run() {
BufferedReader br2 = null;
try {
br2 = new BufferedReader(new InputStreamReader(is2, "GBK"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
try {
String line2 = null ;
while ((line2 = br2.readLine()) != null ) {
if (line2 != null){}
System.out.println(line2);
}
} catch (IOException e) {
e.printStackTrace();
}
finally{
try {
is2.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}.start();
//可能导致进程阻塞,甚至死锁
int ret = process.waitFor();
if(overFlag!=null && OVER_FLAG == true){
OVER_FLAG = !OVER_FLAG;//重置
System.out.println("读取到结束标志,执行exe计算成功!!!");
return Result.OK("执行exe计算成功!!!");
}
int exitValue = process.exitValue();
if(exitValue == 0){
System.out.println("执行exe计算成功!!!");
return Result.OK("执行exe计算成功!!!");
}else{
System.out.println("执行exe计算失败!!!");
return Result.error("执行exe计算失败!!!");
}
}catch (Exception ex){
ex.printStackTrace();
try{
process.getErrorStream().close();
process.getInputStream().close();
process.getOutputStream().close();
}
catch(Exception ee){
return Result.error("执行cmd命令错误");
}
return Result.error("执行cmd命令错误");
}
}
/**
* 执行cmd命令,带日志
* @param command 命令
* @param overFlag 结束标志
*/
public static Result<?> executeCmdWithLog(String command,String overFlag,String type,String filePath){
//日志文件
String strDateFormat = "yyyy-MM-dd HH:mm:ss";
SimpleDateFormat sdf = new SimpleDateFormat(strDateFormat);
appendFileContent(filePath, "执行exe:"+type+"(开始运行时间:"+sdf.format(new Date())+")\n");
Runtime runtime = Runtime.getRuntime();
Process process = null;
try {
process = runtime.exec(command);
} catch (IOException e) {
e.printStackTrace();
}
try {
//获取进程的标准输入流
final InputStream is1 = process.getInputStream();
//获取进城的错误流
final InputStream is2 = process.getErrorStream();
//启动两个线程,一个线程负责读标准输出流,另一个负责读标准错误流
if(overFlag!=null) {
new Thread() {
public void run() {
BufferedReader br1 = null;
try {
br1 = new BufferedReader(new InputStreamReader(is1, "GBK"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
try {
String line1 = null;
while ((line1 = br1.readLine()) != null) {
if (line1 != null){}
System.out.println(line1);
if (!"".equals(line1) && line1.contains(overFlag)) {//计算完成标志
System.out.println("计算成功结束标志!!!");
OVER_FLAG = !OVER_FLAG;//重置
interrupt();
break;
}
}
} catch (IOException e) {
e.printStackTrace();
}
finally{
try {
is1.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}.start();
}else{
new Thread() {
public void run() {
BufferedReader br1 = null;
try {
br1 = new BufferedReader(new InputStreamReader(is1, "GBK"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
try {
String line1 = null;
while ((line1 = br1.readLine()) != null) {
if (line1 != null){}
System.out.println(line1);
}
} catch (IOException e) {
e.printStackTrace();
}
finally{
try {
is1.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}.start();
}
new Thread() {
public void run() {
BufferedReader br2 = null;
try {
br2 = new BufferedReader(new InputStreamReader(is2, "GBK"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
try {
String line2 = null ;
while ((line2 = br2.readLine()) != null ) {
if (line2 != null){}
System.out.println(line2);
appendFileContent(filePath, "执行exe:"+type+"报错:"+line2+"\n");
}
} catch (IOException e) {
e.printStackTrace();
}
finally{
try {
is2.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}.start();
//可能导致进程阻塞,甚至死锁
int ret = process.waitFor();
appendFileContent(filePath, "执行exe:"+type+"(结束运行时间:"+sdf.format(new Date())+")");
if(overFlag!=null && OVER_FLAG == true){
OVER_FLAG = !OVER_FLAG;//重置
System.out.println("读取到结束标志,计算成功!!!");
return Result.OK("计算成功!!!");
}
int exitValue = process.exitValue();
if(exitValue == 0){
appendFileContent(filePath, "执行exe"+type+"计算成功!!!\n");
return Result.OK(type+"执行exe计算成功!!!");
}else{
appendFileContent(filePath, "执行exe"+type+"计算失败!!!\n");
return Result.error(type+"执行exe计算失败!!!");
}
}catch (Exception ex){
ex.printStackTrace();
try{
process.getErrorStream().close();
process.getInputStream().close();
process.getOutputStream().close();
}
catch(Exception ee){
appendFileContent(filePath, "执行exe"+type+"计算失败!!!执行cmd命令关闭流异常\n");
return Result.error(type+"执行exe计算失败!!!关闭流异常");
}
appendFileContent(filePath, "执行exe"+type+"计算失败!!!执行cmd命令异常\n");
return Result.error(type+"执行exe计算失败!!!执行cmd命令异常");
}
}
/**
* 追加文件内容:使用FileWriter
* @param filePath
* @param content
*/
public static void appendFileContent(String filePath, String content) {
try {
//打开一个写文件器,构造函数中的第二个参数true表示以追加形式写文件
FileWriter writer = new FileWriter(filePath, true);
writer.write(content);
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 将生成文件、执行文件路径处理为cmd执行命令
* cmd /c D: & cd dam\\1424996459568680961\\dam_base\\front\\grid\\3\\ & 5heat_2015.exe
* @param generateDamBasePath 生成文件路径 D:\dam\
* @param path 执行文件路径 1424996459568680961\dam_base\after\3\STRESS_S3_EXTRACT.OUT
*/
public static String getCommand(String generateDamBasePath,String path){
//文件路径处理为命令
String[] split = generateDamBasePath.split(":");
int i = path.lastIndexOf(File.separator);
String cmd1 = path.substring(0,i);
String cmd2 = path.substring(i+1);
StringBuffer sb = new StringBuffer("cmd /c ");//cmd窗口
sb.append(split[0]);//切换盘符
sb.append(": & cd ");
sb.append(split[1]+cmd1);//进入该目录下
sb.append(" & ");
sb.append(cmd2);//执行exe
String command = sb.toString();
System.out.println(command);
return command;
}
/**
* 将生成文件、执行文件路径处理为wmic执行命令
* "cmd /c wmic process where \"Name='change-matXYZ.exe' and ExecutablePath like 'E:\\\\dam\\\\dam_base1\\\\dam_base\\\\front\\\\grid\\\\9ceshi111\\\\%'\" get ProcessId"
* @param generateDamBasePath 生成文件路径 E:\dam\
* @param path 执行文件路径 dam_base\front\grid\9ceshi111\change-matXYZ.exe
*/
public static String getWmicCommand(String generateDamBasePath,String path){
//文件路径处理为命令
int i = path.lastIndexOf(File.separator);
String cmd1 = path.substring(0,i).replace("\\","\\\\");
String cmd2 = path.substring(i+1);
StringBuffer sb = new StringBuffer("cmd /c wmic process where \"Name='");//cmd\wmic窗口
sb.append(cmd2);
sb.append("' and ExecutablePath like '");
sb.append(generateDamBasePath.replace("\\","\\\\"));
sb.append(cmd1);
sb.append("\\\\%'\" get ProcessId");
String command = sb.toString();
System.out.println(command);
return command;
}
/**
* 执行命令wmic查询进程pid
* @param command
*/
public static Result<?> getProcessIdByExecutablePathAndName(String command){
String line = null;
BufferedReader br = null;
BufferedReader brError = null;
try {
Process process = Runtime.getRuntime().exec(command);
br = new BufferedReader(new InputStreamReader(process.getInputStream(),"GBK"));
while ((line = br.readLine()) != null) {
if (!"".equals(line) && !"ProcessId ".equals(line)) {
System.out.println(line);
Integer processId = Integer.valueOf(line.trim());
return Result.OK(processId);
}
}
brError = new BufferedReader(new InputStreamReader(process.getErrorStream(),"GBK"));
while ((line = brError.readLine()) != null){
if (!"".equals(line)) {
System.out.println(line);
return Result.error(line);
}
}
} catch (Exception e) {
e.printStackTrace();
return Result.error("执行命令wmic查询进程pid报错");
} finally {
if(br != null){
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
return Result.error("执行命令wmic查询进程pid关闭流报错");
}
}
if(brError != null){
try {
brError.close();
} catch (IOException e) {
e.printStackTrace();
return Result.error("执行命令wmic查询进程pid关闭流报错");
}
}
}
return Result.error("执行命令wmic查询进程pid报错");
}
/**
* 根据进程pid杀死进程
* @param processId 进程pid
*/
public static Result<?> killProcessById(String processId){
String command = "cmd /c taskkill /f /pid "+processId;
String line = null;
BufferedReader br = null;
BufferedReader brError = null;
try {
Process process = Runtime.getRuntime().exec(command);
br = new BufferedReader(new InputStreamReader(process.getInputStream(),"GBK"));
while ((line = br.readLine()) != null){
if (!"".equals(line)) {
System.out.println(line);
return Result.OK(line);
}
}
brError = new BufferedReader(new InputStreamReader(process.getErrorStream(),"GBK"));
while ((line = brError.readLine()) != null){
if (!"".equals(line)) {
System.out.println(line);
return Result.error(line);
}
}
} catch (Exception e) {
e.printStackTrace();
return Result.error("根据进程pid杀死进程报错");
} finally {
if(br != null){
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
return Result.error("根据进程pid杀死进程关闭流报错");
}
}
if(brError != null){
try {
brError.close();
} catch (IOException e) {
e.printStackTrace();
return Result.error("根据进程pid杀死进程关闭流报错");
}
}
}
return Result.error("根据进程pid杀死进程报错");
}
/**
* 杀死进程
* @param generateDamBasePath 生成文件路径
* @param path 执行文件路径
* @return
*/
public static Result<?> killProcessByExecutablePathAndName(String generateDamBasePath,String path,String type){
String wmicCommand = getWmicCommand(generateDamBasePath, path);
Result<?> processIdByExecutablePathAndName = getProcessIdByExecutablePathAndName(wmicCommand);
if(processIdByExecutablePathAndName.isSuccess()){
Result<?> killProcessById = killProcessById(processIdByExecutablePathAndName.getResult().toString());
if(killProcessById.isSuccess()){
return Result.OK(type+"中止任务成功!!!");
}else{
return Result.error(type+"中止任务失败!!!根据进程pid杀死进程报错:"+killProcessById.getMessage());
}
}else{
return Result.error(type+"中止任务失败!!!执行命令wmic查询进程pid报错:"+processIdByExecutablePathAndName.getMessage());
}
}
/**
* 杀死进程,带日志
* @param generateDamBasePath 生成文件路径
* @param path 执行文件路径
* @return
*/
public static Result<?> killProcessByExecutablePathAndNameWithLog(String generateDamBasePath,String path){
String wmicCommand = getWmicCommand(generateDamBasePath, path);
Result<?> processIdByExecutablePathAndName = getProcessIdByExecutablePathAndName(wmicCommand);
if(processIdByExecutablePathAndName.isSuccess()){
Result<?> killProcessById = killProcessById(processIdByExecutablePathAndName.getResult().toString());
if(killProcessById.isSuccess()){
return Result.OK(killProcessById.getResult());
}else{
return Result.error("根据进程pid杀死进程报错:"+killProcessById.getMessage());
}
}else{
return Result.error("执行命令wmic查询进程pid报错:"+processIdByExecutablePathAndName.getMessage());
}
}
public static void main(String [] args) {
//============================测试杀死进程=========================================
// Result<?> killProcessByExecutablePathAndName = killProcessByExecutablePathAndName("E:\\dam\\", "dam_base1\\dam_base\\front\\grid\\9ceshi111\\change-matXYZ.exe");
// System.out.println(killProcessByExecutablePathAndName);
//============================测试pid杀死进程=========================================
// Result<?> killProcessById = killProcessById("3712");
// System.out.println(killProcessById);
//============================测试获取exePid/执行wmic命令=============================
// String wmicCommand = getWmicCommand("E:\\dam\\", "dam_base1\\dam_base\\front\\grid\\9ceshi111\\change-matXYZ.exe");
// Result<?> processIdByExecutablePathAndName = getProcessIdByExecutablePathAndName(wmicCommand);
// System.out.println(processIdByExecutablePathAndName);
//============================测试执行exe文件=========================================
// Result<?> executeCmd= executeCmd("cmd /c D: & cd \\dam\\d61222c4459e4b1dac5d54bc9c2e133f\\dam_base\\cloud & saptis7.5_6_ac_2_20200701.exe","finished !!!");
// Result<?> executeCmd= executeCmd("cmd /c E: & cd \\dam & saptis7.5_6_ac_2_20200701.exe","finished !!!" );
// executeCmdNew("cmd /c E: & cd \\dam\\a25de1e0f6ac4519b253d1732feb7bab & saptis7.5_6_ac_2_20200701.exe","finished !!!" );
// Result<?> executeCmd= executeCmd("cmd /c D: & cd \\dam\\0e4512053a5c4f208110f83bb964d422\\dam_base\\after\\cloud_chart & GIDRESULT7.1.exe",null);
Result<?> executeCmd= executeCmd("cmd /c E: & cd \\dam\\dam_base1\\dam_base\\after\\1ceshi111 & Temp_Extract_7.3.exe","FINISHED AT 540");
// Result<?> executeCmd= executeCmd("cmd /c E: & cd \\dam\\4 & add_crack.exe","thicken jelm finished!");
// Result<?> executeCmd= executeCmd("cmd /c E: & cd \\dam\\5 & sanre.exe","PROGRAM STOP NORMALLY !");
// Result<?> executeCmd= executeCmd("cmd /c E: & cd \\dam\\6 & yueshu.exe",null);
// Result<?> executeCmd= executeCmd("cmd /c E: & cd \\dam\\6 & yueshu.exe",null);
// Result<?> executeCmd= executeCmd("cmd /c E: & cd \\dam\\cs\\7 & pipe_change.exe",null);
// Result<?> executeCmd = executeCmd("cmd /c D: & cd \\dam\\1427505697733971970\\dam_base\\front\\grid\\3 & automesh2015.exe");
// Result<?> executeCmd = executeCmd("cmd /c E: & cd \\dam\\dam_base1\\dam_base\\front\\grid\\999 & change-matXYZ.exe",null);
// Result<?> executeCmd= executeCmd("cmd /c E: & cd \\dam\\dam_base1\\dam_base\\after\\3ceshi & STRESS_Extract_7.3_FAC.exe",null);
// String command = getCommand("E:\\dam\\", "dam_base1\\dam_base\\after\\3ceshi111\\STRESS_Extract_7.3_FAC.exe");
// Result<?> executeCmd = executeCmd(command,null);
System.out.println(executeCmd);
System.out.println("1111");
System.out.println("2222");
}
}