All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.ckjava.utils.CommandUtils Maven / Gradle / Ivy

There is a newer version: 1.0.7
Show newest version
package com.ckjava.utils;

import java.awt.Robot;
import java.awt.event.KeyEvent;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class CommandUtils {
	
	private static Logger logger = LoggerFactory.getLogger(CommandUtils.class);
	
	/**
	 * 执行命令
	 * 
	 * @param command 命令
	 * @param envp String 数组,像 name=value, 可以为空
	 * @param dir 命令执行的时候所在的目录
	 * @param charset 执行命令所在系统的编码
	 * @param output {@code StringBuffer} 对象, 命令的输出
	 */
	public static void execTask(String command, String[] envp, File dir, String charset, StringBuffer output) {
		logger.info("thread name = {}, start execute command = {}", new Object[]{Thread.currentThread().getName(), command});
		Runtime run = Runtime.getRuntime();//返回与当前 Java 应用程序相关的运行时对象
		
		Process proc = null;
		ExecutorService executorService = Executors.newFixedThreadPool(2);
		try {
			proc = run.exec(command, envp, dir);// 启动另一个进程来执行命令
			// 读取错误输出
			Future errorFuture = executorService.submit(new StreamGobbler(proc.getErrorStream(), charset, output));
			// 读取正常输出
			Future normalFuture = executorService.submit(new StreamGobbler(proc.getInputStream(), charset, output));
		    // 检查命令是否执行失败 0 表示正常终止, 这种情况通常是 "java -jar ..." 之类的命令会一直在后台执行,无法终止,只有系统重启或者杀死该进程后才能正常
		    if (proc.waitFor() != 0) {
		    	output.append("执行命令没有正常终止");
		    	logger.error("执行命令没有正常终止");
		        if (proc.exitValue() == 1) { // p.exitValue()==0表示正常结束,1:非正常结束
		        	logger.error("执行命令没有正常返回结果,执行失败");
		        	output.append(",执行命令没有正常返回结果,执行失败");
		        }
		        
		    }
		    
		    errorFuture.get();
		    normalFuture.get();
		} catch (Exception e) {
			logger.error("执行命令出现异常", e);
			output.append("执行命令出现异常");
		} finally {
			try {
				proc.destroy();
				executorService.shutdown();
			} catch (Exception e2) {
			}
		
			logger.info("thread name = {}, finish execute command = {}", new Object[]{Thread.currentThread().getName(), command});
		}
	}

	/**
	 * 执行命令并将输出写出到 OutputStream 中
	 * 
	 * @param command 命令
	 * @param envp String 数组,像 name=value, 可以为空
	 * @param dir 命令执行的时候所在的目录
	 * @param charset 执行命令所在系统的编码
	 * @param output {@code OutputStream} 对象,命令的输出
	 */
	public static void execTask(String command, String[] envp, File dir, String charset, OutputStream output) {
		logger.info("thread name = {}, start execute command = {}", new Object[]{Thread.currentThread().getName(), command});
		Runtime run = Runtime.getRuntime();//返回与当前 Java 应用程序相关的运行时对象
		
		Process proc = null;
		ExecutorService executorService = Executors.newFixedThreadPool(2);
		try {
			proc = run.exec(command, envp, dir);// 启动另一个进程来执行命令
			// 读取错误输出
			Future errorFuture = executorService.submit(new WriteToStream(proc.getErrorStream(), charset, output));
			// 读取正常输出
			Future normalFuture = executorService.submit(new WriteToStream(proc.getInputStream(), charset, output));
			// 接收socket输入
			// executorService.submit(new RobotThread(socketInput));
			// 检查命令是否执行失败 0 表示正常终止, 这种情况通常是 "java -jar ..." 之类的命令会一直在后台执行,无法终止,只有系统重启或者杀死该进程后才能正常
		    if (proc.waitFor() != 0) {
		    	writeString("执行命令没有正常终止", output);
		    	logger.error("执行命令没有正常终止");
		        if (proc.exitValue() == 1) { // p.exitValue()==0表示正常结束,1:非正常结束
		        	writeString("执行命令没有正常返回结果,执行失败", output);
		        	logger.error("执行命令没有正常返回结果,执行失败");
		        }
		    }
		    
		    errorFuture.get();
		    normalFuture.get();
		} catch (Exception e) {
			logger.error("执行命令出现异常", e);
			writeString("执行命令出现异常", output);
		} finally {
			try {
				proc.destroy(); 
				executorService.shutdown();	
			} catch (Exception e2) {
			}
			logger.info("thread name = {}, finish execute command = {}", new Object[]{Thread.currentThread().getName(), command});
		}
		
	}
	
	/**
	 * 执行命令并将输出写出到 OutputStream 中
	 * 
	 * @param command 命令
	 * @param envp String 数组,像 name=value, 可以为空
	 * @param dir 命令执行的时候所在的目录
	 * @param charset 执行命令所在系统的编码
	 * @param startRobotSign 启动机器人
	 * @param output {@code OutputStream} 对象,命令的输出
	 */
	public static void execTask(String command, String[] envp, File dir, String charset, String startRobotSign, OutputStream output) {
		logger.info("thread name = {}, start execute command = {}", new Object[]{Thread.currentThread().getName(), command});
		Runtime run = Runtime.getRuntime();//返回与当前 Java 应用程序相关的运行时对象
		
		Process proc = null;
		ExecutorService executorService = Executors.newFixedThreadPool(3);
		try {
			proc = run.exec(command, envp, dir);// 启动另一个进程来执行命令
			// 读取错误输出
			Future errorFuture = executorService.submit(new WriteToStream(proc.getErrorStream(), charset, output));
			// 读取正常输出
			Future normalFuture = executorService.submit(new WriteToStream(proc.getInputStream(), charset, output));
			// 启动机器人线程
			Future robotFuture =  executorService.submit(new RobotThread(startRobotSign));
			// 检查命令是否执行失败 0 表示正常终止, 这种情况通常是 "java -jar ..." 之类的命令会一直在后台执行,无法终止,只有系统重启或者杀死该进程后才能正常
		    if (proc.waitFor() != 0) {
		    	writeString("执行命令没有正常终止", output);
		    	logger.error("执行命令没有正常终止");
		        if (proc.exitValue() == 1) { // p.exitValue()==0表示正常结束,1:非正常结束
		        	writeString("执行命令没有正常返回结果,执行失败", output);
		        	logger.error("执行命令没有正常返回结果,执行失败");
		        }
		    }
		    
		    errorFuture.get();
		    normalFuture.get();
		    robotFuture.get();
		} catch (Exception e) {
			logger.error("执行命令出现异常", e);
			writeString("执行命令出现异常", output);
		} finally {
			try {
				proc.destroy(); 
				executorService.shutdown();	
			} catch (Exception e2) {
			}
			logger.info("thread name = {}, finish execute command = {}", new Object[]{Thread.currentThread().getName(), command});
		}
	}
	
	private static class RobotThread implements Runnable {
		private String startRobotSign;
		
		public RobotThread(String startRobotSign) {
			super();
			this.startRobotSign = startRobotSign;
		}

		@Override
		public void run() {
			long current = System.currentTimeMillis();
			while (true) {
				long now = System.currentTimeMillis();
	    		if (now - current >= 1000) { // 每秒检查一次
	    			current = now;
	    			logger.info("robot wait to start");
	    			File file = new File(startRobotSign);
	    			if (file.exists()) {
	    				logger.info("start robot");
	    				try {
				    		Robot robot = new Robot();
				    		robot.keyPress(KeyEvent.VK_Q);
				    		robot.keyRelease(KeyEvent.VK_Q);
				    		robot.keyPress(KeyEvent.VK_ENTER);
				    		robot.keyRelease(KeyEvent.VK_ENTER);
				    		file.delete();
				    		logger.info("robot send Q success");
				    		break;
						} catch (Exception e) {
							logger.error("robot send Q has error", e);
							break;
						}
	    			}
	    		}
			}
		}
		
	}

	private static class StreamGobbler implements Runnable {
		private InputStream is; // Process 正常和错误输出流
		private StringBuffer output; // 输出信息
		private String charset;

		private StreamGobbler(InputStream is, String charset, StringBuffer output) {
	        this.is = is;
	        this.output = output;
	        this.charset = charset;
	    }  
	  
	    public void run() {
	    	BufferedReader inReader = null;
	    	String tempStr = null;
	        try {
	            inReader = new BufferedReader(new InputStreamReader(is, Charset.forName(charset)));
			    while ((tempStr = inReader.readLine()) != null) {
			    	output.append(tempStr).append("\n");
			    }
	        } catch (IOException e) {
	        	logger.error("read Process InputStream has error", e);
            } finally {
                try {
                    inReader.close();
                } catch (Exception e) {
                }
            }
	    }
	}
	
	private static class WriteToStream implements Runnable {
	    private InputStream input; // Process stream
	    private OutputStream output; // don't close!
	    private String charset;
	    
	    private WriteToStream(InputStream input, String charset, OutputStream output) {
	        this.input = input;
	        this.charset = charset;
	        this.output = output;
	    }
	    
	    public void run() {
	    	BufferedReader inReader = null;
	        try {
	            inReader = new BufferedReader(new InputStreamReader(input, Charset.forName(charset)));

	            String tempStr = null;
			    while ((tempStr = inReader.readLine()) != null) {
			    	writeString(tempStr, output);
			    }
	        } catch (IOException ioe) {
	        	logger.error("WriteToStream has error", ioe);
            } finally {
                try {
                	input.close();
                    inReader.close();
                } catch (Exception e) {
                }
            }
	    }
	}
	
	/**
	 * 向 OutputStream流中写入String 字符串
	 * 
	 * @param message 字符串
	 * @param output {@code OutputStream} 对象
	 */
	private static void writeString(String message, OutputStream output) {
        try {
        	DataOutputStream dos = new DataOutputStream(output); // 外部输出流,不要关闭
        	dos.writeUTF(message);
            dos.flush();
        } catch (IOException e) {
        	logger.info("CommandUtils writeString method has error", e);
        }
    }
	
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy