java Runtime执行命令

7 篇文章 0 订阅

每个 Java 应用程序都有一个 Runtime 类实例,使应用程序能够与其运行的环境相连接。可以通过 getRuntime 方法获取当前运行时。 应用程序不能创建自己的 Runtime 类实例。我们可以通过 Runtime.exec()用来执行外部程序或命令

Runtime.exec() 有四种调用方法

  • public Process exec(String command);
  • public Process exec(String [] cmdArray);
  • public Process exec(String command, String [] envp);
  • public Process exec(String [] cmdArray, String [] envp);

demo

下面通过一个Demo来 展示 如何用Java来调用Windows上的wmic命令来获取系统中当前的进程信息。

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

public class RuntimeExecTest {
    /**
     * @param args
     */
    public static void main(String[] args) {
        test();
    }

    private static void test() {
	//linux  cmd命令
	Runtime.getRuntime().exec(new String[]{"/bin/sh","-c","javap -l xxx > output.txt"});//通过bin/sh  解释执行该命令

		//Windows  cmd
//        String[] cmd = new String[]{"shutdown" ,"-s" ,"-t" ,"3600"};//定时关机
        String[] cmd = new String[]{"cmd" ,"-s" ,"-t" ,"3600"};//定时关机

//        String[] cmd = new String[]{"cmd.exe", "/C", "wmic process get name"};

        // 输出aaa到1.txt  然后 使用记事本打开该文件
        String command = "cmd /c echo aaa >> d:\\1.txt && notepad d:\\1.txt";// && 命令之间需连接符连接
        try {
            Process process = Runtime.getRuntime().exec(command,null); 
            new Thread(new SerializeTask(process.getInputStream())).start();
            new Thread(new SerializeTask(process.getErrorStream())).start();
            process.getOutputStream().close();
            int exitValue = process.waitFor();
            System.out.println("返回值:" + exitValue);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

/**
 * 打印输出线程
 */
class SerializeTask implements Runnable {
    private InputStream in;

    public SerializeTask(InputStream in) {
        this.in = in;
    }

    @Override
    public void run() {
        BufferedReader br = null;
        try {
            br = new BufferedReader(new InputStreamReader(in));
            String line = null;
            while ((line = br.readLine()) != null) {
                System.out.println(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (br != null)
                    br.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

注意事项

  • 等待命令执行结束用waitFor(),其返回值就是命令的返回值。
  • 如果出现程序执行被挂起,没有任何反应的情况,是由于没有读取命令子进程的正常输出流或错误输出流导致缓冲区被占满,进程被锁住。这个时候需要把输出流中的内容给读出来。最好的做法是使用两个线程,分别同时读取正常输出流和错误输出流。
  • 执行Windows平台上的命令时使用cmd.exe /C,如cmd.exe /C dir
  • 记得关闭命令子进程的输出流,通过Process.getOutputStream().close(),这样不会导致命令子进程被锁住。
  • Runtime.exec() 不等同于直接执行command line命令。Runtime.exec()很有局限性,对有些命令不能直接把command line里的内容当作String参数传给exec().比如重定向等命令。举个例子:javap -l xxx > output.txt。这时要用到exec的第二种重载,即input 参数为String[]:Process p = Runtime.getRuntime().exec(new String[]{"/bin/sh","-c","javap -l xxx > output.txt"});//通过bin/sh 解释执行该命令

部分cmd命令需要cmd解释器来执行【在系统内不存在相应notepad.exe ping.exe等具体可执行文件】,所以java Runtime执行dir会报错,,需要使用cmd /c dir
/c : 打开命令窗口执行完毕自动关闭
/k:打开命令窗口执行完毕不自动关闭

可以通过win+R 打开测试 notepad 类型的命令是在系统内存在notepad d:\1.txt
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

eg.通过命令行统计内存

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

public class 统计内存 {

    /**
     * @param args
     */
    public static void main(String[] args) throws IOException {
        test();
    }

    /**
     * 统计每个进程占用多少内存
     *
     * @throws IOException
     */
    private static void test() throws IOException {

//        String command = "cmd /c tasklist | findstr svchost.exe";// 查看内存
        String command = "cmd /c tasklist ";// 查看内存
        try {
            Process process = Runtime.getRuntime().exec(command, null);

            SerializeTask target = new SerializeTask(process.getInputStream());
            SerializeTask err = new SerializeTask(process.getErrorStream());

            new Thread(target).start();//开启线程读取返回值
            new Thread(err).start();//开启线程读取错误返回
            process.getOutputStream().close();
            int exitValue = process.waitFor();//等待结束
            System.out.println(target.res);

            //正则解析结果
            Pattern compile = Pattern.compile("(.+)\\s+\\d+\\s+\\w+\\s+\\d\\s+(\\d.+K)");
            Matcher matcher = compile.matcher(target.res);
            int total = 0;
            Map<String, Integer> map = new HashMap<>();

            while (matcher.find()) {
                int me = ConversionFormat(matcher.group(2));
                total += me;

                String name = matcher.group(1);
                if (map.containsKey(name)) {
                    map.put(name, map.get(name) + me);
                } else {
                    map.put(name, me);
                }

            }
            System.out.println("总共占用内存 " + total);

            System.out.println("=================");
            System.out.println(map);

            //解析结果结束

            System.out.println("运行返回值:" + exitValue);

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    /**
     * 转换数据格式  7,752 K   7752
     *
     * @param group
     * @return
     */
    private static int ConversionFormat(String group) {
        String replace = group.replace(",", "");
        String replace1 = replace.replace(" K", "");
        return Integer.parseInt(replace1) / 1024;
    }
}

/**
 * 打印输出线程
 */
class SerializeTask implements Runnable {
    private InputStream in;
    String res = "";

    public SerializeTask(InputStream in) {
        this.in = in;
    }

    @Override
    public void run() {
        BufferedReader br = null;
        try {
            br = new BufferedReader(new InputStreamReader(in, "gbk"));
            String line = null;
            while ((line = br.readLine()) != null) {
//                System.out.println(line);
                res = res + line + "\r\n";
            }

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (br != null) {
                    br.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值