Java 调用CMD 命令行 经典实例

有很多的时候需要使用命令行去做一些操作,简单的调用命令行或者bat批处理文件不一定能满足要求;由于公司里边要手动去刷公司应用包到安卓目标设备上去,再重启安装,全部都要手动敲命令行,甚是繁琐,故本人制作了一个Java调用命令行的工具。

还有很多可以改进的地方,如可以定义单个命令的超时时间,单个命令的返回解析等等。如果读者有需要,可以自行更改。

转载请注明出处!

下面贴代码:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.TimeUnit;

public class CmdProcessor {
	private Process mProcess; // the cmd process
	private PrintWriter mWriter; // write cmd streams to process
	private BufferedReader mReader; // log the cmd response
	private volatile boolean mStop; // stop the process
	private LinkedBlockingDeque mCmds; // the cmd container
	private boolean mLoggable = true; // print log
	private boolean mWarnTimeout = false;
	private long mTimeoutMillis = 30 * 1000; // 30s

	protected long mCmdStartMillis; // record the cmd start time
	protected long mProStartMillis; // record the process start time

	public CmdProcessor() {
		this(null);
	}

	public CmdProcessor(Collection cmds) {
		mCmds = new LinkedBlockingDeque();
		if (cmds != null) {
			mCmds.addAll(cmds); // here is your cmds
		}
	}

	private void init() throws IOException {
		mProcess = Runtime.getRuntime().exec("cmd", getEnvs());
		mReader = new BufferedReader(new InputStreamReader(mProcess.getInputStream()));
		mWriter = new PrintWriter(new OutputStreamWriter(mProcess.getOutputStream()));
		mCmdStartMillis = System.currentTimeMillis();
		mProStartMillis = mCmdStartMillis;

		if (mWarnTimeout) {
			warnTimeout();
		}
	}

	private String[] getEnvs() {
		LinkedList envList = new LinkedList();
		Map envMap = System.getenv();
		for (Entry env : envMap.entrySet()) {
			if (!env.getKey().contains("=") && !env.getValue().contains("=")) {
				envList.add(env.getKey() + "=" + env.getValue());
			}
		}
		String[] evns = new String[envList.size()];
		return envList.toArray(evns);
	}

	public void addFirst(String cmd) {
		mCmds.addFirst(cmd);
	}

	public void addLast(String cmd) {
		mCmds.addLast(cmd);
	}

	public void add(String cmd) {
		addLast(cmd);
	}

	/**
	 * Print warning if cmd has no response, you can disable it
	 */
	private void warnTimeout() {
		new Thread(new Runnable() {

			@Override
			public void run() {
				while (!mStop) {
					long passedSec = (System.currentTimeMillis() - mCmdStartMillis);
					if (passedSec > mTimeoutMillis) {
						System.out.println("[" + mCmds.peek() + "] cost seconds:" + passedSec / 1000);
					}
					try {
						Thread.sleep(1050);
					} catch (InterruptedException e) {
					}
				}
			}
		}).start();
	}

	public void setLoggable(boolean loggable) {
		mLoggable = loggable;
	}

	public void waitFor() throws InterruptedException, IOException {
		mProcess.waitFor();
		stop();
	}

	public void waitFor(final long timeout, TimeUnit timeUnit) throws Exception {
		String versionStr = System.getProperty("java.version");
		float version = Float.valueOf(versionStr.substring(0, 3));
		if (version >= 1.8f) {
			mProcess.waitFor(timeout, timeUnit);
		} else {
			mockupWaitFor(timeout, timeUnit);
		}
		stop();
	}

	/**
	 * If JDK level is lower than 1.8, you can't use method
	 * Process.waitFor(long, TimeUnit). So here mock up a waitFor(long,
	 * TimeUnit) method.
	 * 
	 * @param timeout
	 * @throws Exception
	 */
	private void mockupWaitFor(long timeout, TimeUnit timeUnit) throws Exception {
		final long timeMillis = timeUnit.toMillis(timeout);
		final Object tmpLock = new Object();

		new Thread(new Runnable() {

			@Override
			public void run() {
				long start = System.currentTimeMillis();
				while (true) {
					if (System.currentTimeMillis() - start > timeMillis) {
						synchronized (tmpLock) {
							tmpLock.notify();
						}
						break;
					}

					try {
						Thread.sleep(1);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		}).start();

		synchronized (tmpLock) {
			tmpLock.wait();
		}
	}

	private void executeCmd(String cmd) {
		if (!mStop) {
			mWriter.println(cmd);
			mWriter.flush();
			mCmdStartMillis = System.currentTimeMillis();
		}
	}

	public void start() throws Exception {
		init();

		System.out.println();

		new Thread(new Runnable() {

			@Override
			public void run() {
				try {
					processCmds();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}).start();
	}

	public void stop() throws IOException {
		mStop = true;
		mProcess.destroy();
		mReader.close();
		mWriter.close();
	}

	public boolean isStopped() {
		return mStop;
	}

	private void processCmds() throws Exception {
		boolean firstReply = true;
		StringBuffer buffer = new StringBuffer();
		char[] chars = new char[1024];
		while (!mStop) {
			if (mReader.ready()) {
				int len = mReader.read(chars);
				buffer.append(chars, 0, len);
				if (mLoggable) {
					System.out.print(new String(chars, 0, len));
				}
			} else {
				String log = buffer.toString();
				boolean isReply = isCmdReply(mCmds.peek(), log);
				if (isReply) {
					buffer.delete(0, buffer.length());

					if (firstReply) {
						firstReply = false;
					} else {
						onCmdReply(mCmds.poll(), log); // on cmd reply
					}

					if (mCmds.peek() == null) { // process next cmd
						onFinish();
					} else {
						String nextCmd = mCmds.peek();
						preExecuteCmd(nextCmd);
						executeCmd(nextCmd);
					}
				}
			}
		}
	}

	// reply???
	protected boolean isCmdReply(String cmd, String log) throws Exception {
		String userDir = System.getProperty("user.dir");
		return log.contains(userDir);
	}

	// on cmd reply
	protected void onCmdReply(String cmd, String reply) throws Exception {

	}

	// pre-execute cmd
	protected void preExecuteCmd(String cmd) throws Exception {

	}

	// all the cmds has been executed
	protected void onFinish() throws Exception {
		stop();

		if (mLoggable) {
			long costSec = (System.currentTimeMillis() - mProStartMillis) / 1000;
			System.out.println("\nCost time: " + costSec);
		}
	}

	public static void main(String[] args) throws Exception {
		CmdProcessor pro = new CmdProcessor();
		pro.addFirst("dir");
		pro.start();

		List cmds = new LinkedList<>();
		cmds.add("dir /a");
		CmdProcessor cd = new CmdProcessor(cmds);
		cd.start();
	}
}



你可能感兴趣的:(Android,Java)