Java Process详解及实例

参考链接:

Java Process详解及实例_JAVA教程_服务器之家

Java中Process类的使用与注意事项_Kevin.Yang的博客-CSDN博客_process类使用


Part1

原文链接:Java Process详解及实例_JAVA教程_服务器之家

Java可以通过Runtime来调用其他进程,如cmd命令,shell文件的执行等。可以应该该类设置系统时间,执行shell文件。此处记录几个有用应用如下。

设置本地时间

可以调用cmd /c date命令,完成本地时间设置,不过这个命令在win7下可以使用,但是win10需要管理员权限,可能无法设置系统时间。win7下使用Java实现修改本地时间代码如下,需要注意的是waitFor是必须的,否则无法立即生效。

此处注意的是,读取流信息的时候,有可能流对象太大,
不能一次性读完,导致获取的字符串顺序错乱或缺失的问题,
所以我们等程序执行完毕之后再去读取
waitFor会让线程阻塞,直至process执行完毕
/**
  * 设置本地日期
  * @param date yyyy-MM-dd格式
  */
 private static void setSystemDate(String date){
   Process process = null;
   String command1 = "cmd /c date "+date;
   System.out.println(command1);
   try {
     process = Runtime.getRuntime().exec(command1);
     //必须等待该进程结束,否则时间设置就无法生效
     process.waitFor();
   } catch (IOException | InterruptedException e) {
     e.printStackTrace();
   }finally{
     if(process!=null){
       process.destroy();
     }
   }
 }

网卡吞吐量计算

可以通过cat /proc/net/dev命令获取网卡信息,两次获取网卡发送和接收数据包的信息,来计算网卡吞吐量。实现如下:

/**
  * @Purpose:采集网络带宽使用量
  * @param args
  * @return float,网络带宽已使用量
  */
 public static Double getNetworkThoughput() {
    Double curRate = 0.0;
   Runtime r = Runtime.getRuntime();
 
   // 第一次采集流量数据
   long startTime = System.currentTimeMillis();
   long total1 = calculateThoughout(r);
 
   // 休眠1秒后,再次收集
   try {
     Thread.sleep(1000);
   } catch (InterruptedException e) {
     e.printStackTrace();
   }
 
   // 第二次采集流量数据
   long endTime = System.currentTimeMillis();
   long total2 = calculateThoughout(r);
 
   // 计算该段时间内的吞吐量:单位为Mbps(million bit per second)
   double interval = (endTime-startTime)/1000;
   curRate = (total2-total1)*8/1000000*interval;
 
   System.out.println("收集网络带宽使用率结束,当前设备的网卡吞吐量为:"+(curRate)+"Mbps.");
   return curRate;
 }
 
 /**
  * 计算某个时刻网卡的收发数据总量
  * @param runtime
  * @return
  */
 private static long calculateThoughout(Runtime runtime){
   Process process = null;
   String command = "cat /proc/net/dev";
   BufferedReader reader = null;
   String line = null;
   long total = 0;
   try {
     process = runtime.exec(command);
     reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
     while ((line = reader.readLine()) != null) {
       line = line.trim();
       // 考虑多网卡的情况
       if (line.startsWith("eth")) {
         log.debug(line);
         line = line.substring(5).trim();
         String[] temp = line.split("\\s+");
         total+=(Long.parseLong(temp[0].trim()));// Receive
         total+=(Long.parseLong(temp[8].trim()));// Transmit
       }
     }
   } catch (NumberFormatException | IOException e) {
     e.printStackTrace();
   } finally {
     if (reader != null) {
       try {
         reader.close();
       } catch (IOException e) {
         // TODO Auto-generated catch block
         e.printStackTrace();
       }
     }
 
     if (process != null) {
       process.destroy();
     }
   }
   return total;
 }


Part2 

原文链接:Java中Process类的使用与注意事项_Kevin.Yang的博客-CSDN博客_process类使用

在项目开发中,经常会遇到调用其它程序功能的业务需求,在java中通常有两种实现方法

Runtime runtime = Runtime.getRuntime();
Process p = runtime.exec(cmd);
Process process = Runtime.getRuntime().exec(new String[]{"cmd.exe", "/c", "xxxx"});
Process p=new ProcessBuilder(cmd).start();

在这里就需要认识一下process类:process是一个抽象的类,它包含6个抽象的方法

abstract public OutputStream getOutputStream();


abstract public InputStream getInputStream();


abstract public InputStream getErrorStream();


abstract public int waitFor() throws InterruptedException;


abstract public int exitValue();


abstract public void destroy();

process类提供获取子进程的输入流、子进程的输出流、子进程的错误流、等待进程完成、检查进程的推出状态以及销毁进程的方法;在这里需要提及的是创建的子进程没有自己的控制台或终端,其所有的io操作都是通过(输入流、输出流、错误流)重定向到父进程中。

来说说今天业务需求[waitfor()]:我需要在linux下首先将一个文件copy到指定的文件夹下面,之后需要将该文件夹下面的文件加入指定的jar中,那么问题就来了,必须保证其先后顺序,也就书说再执行第二个命令的时候第一个命令必须完成。

    public void cmd(String cmd){
        try {
            Process ps= Runtime.getRuntime().exec(cmd); 
        } catch (Exception e) {
            logger.info(e.getMessage(),e);
        }
    }

main函数如下:

public static void main(String[] args){
     String copy="cp -rf "+source+" "+target;
     String jar="jar -uvf "+jar+" "+file;
     cmd(copy);
     cmd(jar);
}

但是结果是新生成的jar中压根没有新加入的文件,但是文件确实copy到了指定的文件夹中,也就是谁两个命令都执行了,问题的关键就是“异步”,这时候需要waitFor()的介入

    public void cmd(String cmd){
        try {
            Process ps= Runtime.getRuntime().exec(cmd); 
            ps.waitFor();
        } catch (Exception e) {
            logger.info(e.getMessage(),e);
        }
    }

那么问题就解决了!

这位作者

前不久遇到一个奇怪的问题就是ajax调用没有返回值,我在service中实现了process的调用。

String[] commands = { commandGenerate,commandPublish};
        PrintWriter printWriter = response.getWriter();
        for (String comm : commands) {
            Runtime runtime = Runtime.getRuntime();
            try {
                logger.info("command is :{}",comm);
                Process process = runtime.exec(comm, null, null);
                BufferedInputStream inputStream = new BufferedInputStream(
                        process.getInputStream());
                BufferedReader bufferedReader = new BufferedReader(
                        new InputStreamReader(inputStream));
                String line;
                while (bufferedReader.read() != -1) {
                    line = bufferedReader.readLine();
                    System.out.println(line);
                }
                bufferedReader.close();
                inputStream.close();
                printWriter.println("success");
            } catch (IOException e) {
                logger.error(e.getMessage(), e);
                printWriter.println(e.getMessage());
            }
        }
        printWriter.flush();
        printWriter.close();

对应的controller为:

       State state = new State();
        String message="";
        try {
            message = missionService.syntax(taskName, response);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        state.setSuccess(true);
        state.setMessage(message.trim());
        return state;

打印state.getMessage()确实可以获得值,但是state返回就是空,刚开始以为是ajax的timeout时间的问题:修改了ajax的timeout时间仍然不行;将message直接赋值,然thread等待20s,结果是可以返回的,所以问题最终定为于service的这段实现。

原因分析:在上面提及了,process创建的子进程没有自己的控制台或终端,其所有的io操作都是通过(输入流、输出流、错误流)重定向到父进程中,如果该可执行程序的输入、输出或者错误输出比较多的话,而由于运行窗口的标准输入、输出等缓冲区有大小的限制,则可能导致子进程阻塞,甚至产生死锁,其解决方法就是在waitfor()方法之前读出窗口的标准输出、输出、错误缓冲区中的内容。
 

for (String comm : commands) {
            logger.info("the comm time is:"+new Date().getTime()+" the comm is:"+comm);
            Runtime runtime = Runtime.getRuntime();
            Process p=null;
            try {  
                 p = runtime.exec(comm ,null,null);         
                 final InputStream is1 = p.getInputStream();   
                 final InputStream is2 = p.getErrorStream();  
                 new Thread() {  
                    public void run() {  
                       BufferedReader br1 = new BufferedReader(new InputStreamReader(is1));  
                        try {  
                            String line1 = null;  
                            while ((line1 = br1.readLine()) != null) {  
                                  if (line1 != null){
                                      logger.info("p.getInputStream:"+line1);
                                      if(line1.indexOf("syntax check result:")!=-1){
                                          builder.append(line1);
                                      }
                                  }  
                              }  
                        } catch (IOException e) {  
                             e.printStackTrace();  
                        }  
                        finally{  
                             try {  
                               is1.close();  
                             } catch (IOException e) {  
                                e.printStackTrace();  
                            }  
                          }  
                        }  
                     }.start();  

                   new Thread() {   
                      public void  run() {   
                       BufferedReader br2 = new  BufferedReader(new  InputStreamReader(is2));   
                          try {   
                             String line2 = null ;   
                             while ((line2 = br2.readLine()) !=  null ) {   
                                  if (line2 != null){
                                  }  
                             }   
                           } catch (IOException e) {   
                                 e.printStackTrace();  
                           }   
                          finally{  
                             try {  
                                 is2.close();  
                             } catch (IOException e) {  
                                 e.printStackTrace();  
                             }  
                           }  
                        }   
                      }.start();                                                
                      p.waitFor();  
                      p.destroy();   
                    } catch (Exception e) {  
                            try{  
                                p.getErrorStream().close();  
                                p.getInputStream().close();  
                                p.getOutputStream().close();  
                                }  
                             catch(Exception ee){}  
                   }  
        }  

Part3

原文链接:

编写可执行jar——java的Process类的使用(二)_慕课手记

读取控制台IO流

public class App {

    public static void main(String...args)throws Exception{
        //执行指令
        Process process = Runtime.getRuntime().exec("adb devices");
        System.out.println("【控制台执行信息】");
        System.out.println(readInputstream(process.getInputStream()));
        System.out.println("【控制台错误信息】");
        System.out.println(readInputstream(process.getErrorStream()));

    }

    /**
     * 读取控制台打印的文字
     * @param in
     * @return
     * @throws Exception
     */
    public static String readInputstream(InputStream in) throws Exception{
        InputStream inputStream = in;
        InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
        BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
        StringBuilder sb = new StringBuilder();
        String line = null;
        while((line=bufferedReader.readLine())!=null){
            sb.append(line).append("\n");
        }
        return sb.toString();
    }
}

编写指令词典

package com.zeemoo.nox.actuator.consts;

import lombok.Getter;

/**
 * 夜神模拟器的adb指令词典
 *
 * @author zhang.shushan
 * @date 2018/6/8
 */
@Getter
public class NoxCmdDict {

    /**
     * adb脚本指令
     */
    public final static String ADB = "adb";

    /**
     * 选择模拟器
     */
    public final static String SERVER_HOST = "-s";

    /**
     * 模拟器列表
     */
    public final static String DEVICES = "devices";

    /**
     * 安装apk
     */
    public final static String INSTALL = "install";

    /**
     * 从电脑发送文件到模拟器,没什么卵用,还有权限限制
     */
    @Deprecated
    public final static String PUSH = "push";

    /**
     * 从模拟器拉取文件到电脑,没什么卵用,还有权限限制
     */
    @Deprecated
    public final static String PULL = "pull";

    /**
     * 卸载app
     */
    public final static String UNINSTALL = "uninstall";

    /**
     * shell脚本指令,安卓内核为linux
     */
    public final static String SHELL = "shell";

    /**
     * 列举进程
     */
    public final static String SHELL_PS = "ps";

    /**
     * 包含某个字符串的进程信息
     */
    public final static String SHELL_PS_MTH_FIND_STR ="|findStr";

    /**
     * 包指令
     */
    public final static String SHELL_PM = "pm";

    /**
     * 包指令下的列举指令
     */
    public final static String SHELL_PM_LIST = "list";

    /**
     * 包指令下的列举指令选项,表示列举所有的包名
     */
    public final static String SHELL_PM_LIST_PACKAGES = "packages";

    /**
     * 包指令下的列举指令选项的附加选项,表示列举所有的包名和对应的路径
     */
    public final static String SHELL_PM_LIST_PACKAGES_OP_NAME_AND_PATH = "-f";

    /**
     * 获取某个应用的路径,需要填写包名
     */
    public final static String SHELL_PM_PATH = "path";

    /**
     * 清除应用缓存,后面接包名
     */
    public final static String SHELL_PM_CLEAR_TEMP = "clear";

    /**
     * 应用管理指令(Activity Manager),启动或关闭应用
     */
    public final static String SHELL_AM = "am";

    /**
     * 启动应用,最后接上包名+“/”+Activity类名
     */
    public final static String SHELL_AM_START = "start";

    /**
     * 这个选项表示如果应用启动了就直接打开后台进程,如果没启动则启动。
     * 不加此选项每次调用start的时候则每次都重启应用
     */
    public final static String SHELL_AM_START_OP_XSTART = "-n";

    /**
     * 关闭应用,后接包名
     */
    public final static String SHELL_AM_STOP = "force-stop";

    /**
     * 杀死进程,后接包名,似乎没什么用
     */
    public final static String SHELL_AM_KILL = "kill";

    /**
     * 杀死后台所有进程,似乎没什么用
     */
    public final static String SHELL_AM_KILL_ALL = "kill-all";

    /**
     * shell模拟输入
     */
    public final static String SHELL_INPUT = "input";

    /**
     * 模拟输入文字(不支持中文)
     */
    public final static String SHELL_INPUT_TEXT = "text";

    /**
     * 模拟点击按键
     */
    public final static String SHELL_INPUT_KEYEVENT = "keyevent";

    /**
     * 模拟鼠标点击,后面接X,Y
     */
    public final static String SHELL_INPUT_TAP = "tap";

    /**
     * 模拟鼠标滑动,后面接X1,Y1,X2,Y2
     */
    public final static String SHELL_INPUT_SWIPE = "swipe";

    /**
     * 截屏
     */
    public final static String SHELL_SCREEN_CAP = "screencap";

    /**
     * 截屏选项,后接截屏文件输出目标
     */
    public final static String SHELL_SCREEN_CAP_OP_DEST = "-p";

    /**
     * 退出shell
     */
    public final static String SHELL_EXIT = "exit";

    /**
     * 夜神模拟器的adb
     */
    public final static String NOX_ADB = "nox_adb";

    /**
     * 夜神模拟器属性设置
     */
    public final static String NOX_ADB_SHELL_SET_PROP = "setprop";

    /**
     * 设置手机的纬度
     */
    public final static String NOX_ADB_SHELL_SET_PROP_LATITUDE = "persist.nox.gps.latitude";

    /**
     * 设置模拟器的经度
     */
    public final static String NOX_ADB_SHELL_SET_PROP_LONGITUDE = "persist.nox.gps.longitude";

    /**
     * 设置模拟器的mac地址
     */
    public final static String NOX_ADB_SHELL_SET_PROP_MAC = "setprop persist.nox.wifimac";

}

作者:zee_moo
链接:https://www.imooc.com/article/39924
来源:慕课网
本文原创发布于慕课网 ,转载请注明出处,谢谢合作
 

创建一个Builder类

package com.zeemoo.nox.actuator.service;

import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import lombok.Setter;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

//此处使用静态引入指令词典,可以试着删去这一行,看看有什么区别
import static com.zeemoo.nox.actuator.consts.NoxCmdDict.*;

/**
 * 功能指令构建
 *
 * @author zhang.shushan
 * @date 2018/6/8
 */
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class NoxCmdBuilder {

    /**
     * 夜神模拟器的根目录
     */
    private String noxPath;

    /**
     * 给指令添加指定模拟器
     * @param cmds
     * @param host
     * @return
     */
    public List<String> addHost(List<String> cmds,String host){
        if(host!=null&&"".equals(host)){
            cmds.add(1, SERVER_HOST);
            cmds.add(2,host);
        }
        return cmds;
    }

    /**
     * 筛选字符进程
     * @param example
     * @return
     */
    public List<String> listProcess(String example){

        List<String> cmds=listPackageName();
        cmds.add(SHELL_PS_MTH_FIND_STR);
        cmds.add(example);
        return cmds;
    }

    /**
     * 列举所有的进程
     * @return
     */
    public List<String> listProcess(){
        List<String> cmds = this.shellModal();
        cmds.add(SHELL_PS);
        return cmds;
    }

    /**
     * 列举所有模拟器
     * @return
     */
    public List<String> devices(){
        List<String> cmds = new ArrayList<>();
        cmds.add(noxPath+File.separator+ NOX_ADB);
        cmds.add(DEVICES);
        return cmds;
    }

    /**
     * 启动夜神模拟器
     * @return
     */
    public String startNox(){
        return noxPath+File.separator+"nox.exe";
    }

    /**
     * 截屏
     * @param vitualBoxFilePath
     * @return
     */
    public List<String> screenCap(String vitualBoxFilePath){
        List<String> cmds = new ArrayList<>();
        cmds.add(SHELL_SCREEN_CAP);
        cmds.add(SHELL_SCREEN_CAP_OP_DEST);
        cmds.add(vitualBoxFilePath);
        return cmds;
    }

    /**
     * 模拟滑动屏幕
     * @param x1
     * @param y1
     * @param x2
     * @param y2
     * @return
     */
    public List<String> swipe(int x1,int y1,int x2,int y2){
        List<String> cmds = this.inputModal();
        cmds.add(SHELL_INPUT_SWIPE);
        cmds.add(String.valueOf(x1));
        cmds.add(String.valueOf(y1));
        cmds.add(String.valueOf(x2));
        cmds.add(String.valueOf(y2));
        return cmds;
    }

    /**
     * 模拟点击
     * @param x
     * @param y
     * @return
     */
    public List<String> click(int x,int y){
        List<String> cmds = this.inputModal();
        cmds.add(SHELL_INPUT_TAP);
        cmds.add(String.valueOf(x));
        cmds.add(String.valueOf(y));
        return cmds;
    }

    /**
     * 模拟按键
     * @param keys 按键
     * @return
     */
    public List<String> pressKey(List<String> keys){
        List<String> cmds = this.inputModal();
        cmds.add(SHELL_INPUT_KEYEVENT);
        cmds.addAll(keys);
        return cmds;
    }

    /**
     * 文本输入,不支持中文
     * @param text
     * @return
     */
    public List<String> inputText(String text){
        List<String> cmds = this.inputModal();
        cmds.add(SHELL_INPUT_TEXT);
        cmds.add(text);
        return cmds;
    }

    /**
     * 输入模式
     * @return
     */
    private List<String> inputModal() {
        List<String> cmds = this.shellModal();
        cmds.add(SHELL_INPUT);
        return cmds;
    }

    /**
     * 杀死后台所有进程
     * @return
     */
    public List<String> killAllAppProcess(){
        List<String> cmds = this.activityManager();
        cmds.add(SHELL_AM_KILL_ALL);
        return cmds;
    }

    /**
     * 杀死某个后台进程
     * @param pkgNm
     * @return
     */
    public List<String> killAppProcess(String pkgNm){
        List<String> cmds = this.activityManager();
        cmds.add(SHELL_AM_KILL);
        cmds.add(pkgNm);
        return cmds;
    }

    /**
     * 停止app
     * @param pkgName
     * @return
     */
    public List<String> stopApp(String pkgName){
        List<String> cmds = this.activityManager();
        cmds.add(SHELL_AM_STOP);
        cmds.add(pkgName);
        return cmds;
    }

    /**
     * 启动app
     * @param pkgName
     * @param activity
     * @return
     */
    public List<String> startApp(String pkgName,String activity){
        List<String> cmds = this.activityManager();
        cmds.add(SHELL_AM_START);
        cmds.add(SHELL_AM_START_OP_XSTART);
        cmds.add(pkgName+"/"+activity);
        return cmds;
    }

    /**
     * 获取某个应用的路径
     * @param pkgName
     * @return
     */
    public List<String> getAppPath(String pkgName){
        List<String> cmds = this.packageManager();
        cmds.add(SHELL_PM_PATH);
        cmds.add(pkgName);
        return cmds;
    }

    /**
     *
     * @return
     */
    public List<String> listPackageNameAndPath(){
        List<String> cmds = this.listPackageName();
        cmds.add(SHELL_PM_LIST_PACKAGES_OP_NAME_AND_PATH);
        return cmds;
    }

    /**
     * 列举所有的包名
     * @return
     */
    public List<String> listPackageName(){
        List<String> cmds=this.packageManager();
        cmds.add(SHELL_PM_LIST);
        cmds.add(SHELL_PM_LIST_PACKAGES);
        return cmds;
    }

    /**
     * 包操作指令
     * @return
     */
    private List<String> packageManager(){
        List<String> cmds = this.shellModal();
        cmds.add(SHELL_PM);
        return cmds;
    }

    /**
     * activityManager模式
     * @return
     */
    private List<String> activityManager(){
        List<String> cmds = this.shellModal();
        cmds.add(SHELL_AM);
        return cmds;
    }

    /**
     * 从模拟器拉取文件到电脑,有权限限制
     * @param virtualBoxFilePath
     * @param pcFilePath
     * @return
     */
    @Deprecated
    public List<String> pull(String virtualBoxFilePath,String pcFilePath){
        List<String> cmds = new ArrayList<>();
        cmds.add(noxPath+File.separator+virtualBoxFilePath);
        cmds.add(PULL);
        cmds.add(virtualBoxFilePath);
        cmds.add(pcFilePath);
        return cmds;
    }

    /**
     * 推送文件到模拟器,有权限限制
     * @param pcFilePath
     * @param vitualBoxFilePath
     * @return
     */
    @Deprecated
    public List<String> push(String pcFilePath,String vitualBoxFilePath){
        List<String> cmds = new ArrayList<>();
        cmds.add(noxPath+ File.separator+ NOX_ADB);
        cmds.add(PUSH);
        cmds.add(pcFilePath);
        cmds.add(vitualBoxFilePath);
        return cmds;
    }

    /**
     * 卸载app
     * @param packageName
     * @return
     */
    public List<String> uninstall(String packageName){
        List<String> cmds = new ArrayList<>();
        cmds.add(noxPath+ File.separator+ NOX_ADB);
        cmds.add(UNINSTALL);
        cmds.add(packageName);
        return cmds;
    }

    /**
     * 安装app
     * @param apkPath
     * @return
     */
    public List<String> install(String apkPath){
        List<String> cmds = new ArrayList<>();
        cmds.add(noxPath+ File.separator+ NOX_ADB);
        cmds.add(INSTALL);
        cmds.add(apkPath);
        return cmds;
    }

    /**
     * 设置mac地址
     * @param mac
     * @return
     */
    public List<String> setMac(String mac){
        List<String> cmds = this.shellModal();
        cmds.add(NOX_ADB_SHELL_SET_PROP);
        cmds.add(NOX_ADB_SHELL_SET_PROP_MAC);
        cmds.add(mac);
        return cmds;
    }

    /**
     * 设置经度
     * @param longitude
     * @return
     */
    public List<String> setLongitude(Double longitude){
        List<String> cmds = this.shellModal();
        cmds.add(NOX_ADB_SHELL_SET_PROP);
        cmds.add(NOX_ADB_SHELL_SET_PROP_LONGITUDE);
        cmds.add(longitude.toString());
        return cmds;
    }

    /**
     * 设置模拟器纬度
     * @param latitude
     * @return
     */
    public List<String> setLatitude(Double latitude){
        List<String> cmds = this.shellModal();
        cmds.add(NOX_ADB_SHELL_SET_PROP);
        cmds.add(NOX_ADB_SHELL_SET_PROP_LATITUDE);
        cmds.add(latitude.toString());
        return cmds;
    }

    /**
     * shell模式,设置模拟器属性之类的
     * @return
     */
    private List<String> shellModal(){
        List<String> cmds = new ArrayList<>();
        cmds.add(noxPath+ File.separator+ NOX_ADB);
        cmds.add(SHELL);
        return cmds;
    }

    /**
     * shell模式,清除缓存
     * @return
     */
    public List<String> clearTemp(String pckName) {
        List<String> cmds = this.shellModal();
        cmds.add(SHELL_PM_CLEAR_TEMP);
        cmds.add(pckName);
        return cmds;
    }
}

作者:zee_moo
链接:https://www.imooc.com/article/39924
来源:慕课网
本文原创发布于慕课网 ,转载请注明出处,谢谢合作

测试 

public static void main(String...args)throws Exception{
        NoxCmdBuilder noxCmdBuilder = new NoxCmdBuilder("C:\\Program Files\\Nox\\bin");
        System.out.println(noxCmdBuilder.listPackageName());

}

输出结果:

[C:\Program Files\Nox\bin\nox_adb, shell, pm, list, packages]

直接将这个list放入ProcessBuilder中使用,就可以获得所有的包名了。我们来试一下。修改main如下

public static void main(String... args) throws Exception {
        NoxCmdBuilder noxCmdBuilder = new NoxCmdBuilder("C:\\Program Files\\Nox\\bin");
        Process start = new ProcessBuilder().command(noxCmdBuilder.listPackageName()).start();
        //此处注意的是,读取流信息的时候,有可能流对象太大,
        //不能一次性读完,导致获取的字符串顺序错乱或缺失的问题,
        //所以我们等程序执行完毕之后再去读取
        //waitFor会让线程阻塞,直至process执行完毕
        start.waitFor();
        System.out.println(readInputstream(start.getInputStream()));
}

  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java中的Process是一个抽象类,它继承自Object类。通过使用ProcessBuilder.start()方法或Runtime.exec方法,可以创建一个本机进程的实例,并用于控制该进程以及获取相关信息。Process类提供了执行进程输入、执行进程输出、等待进程完成、检查进程的退出状态以及销毁(杀掉)进程等方法。 以下是一个示例代码,展示了如何使用Process类创建并执行一个ping命令的进程,并打印输出结果: ```java import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; public class ProcessDemo { public static void main(String[] args) { try { Process process = Runtime.getRuntime().exec("ping www.baidu.com"); BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream(), "gbk")); String line; while ((line = bufferedReader.readLine()) != null) { System.out.println(line); } System.out.println("任务执行完毕!"); } catch (IOException e) { e.printStackTrace(); } } } ``` 以上代码使用Runtime.getRuntime().exec("ping www.baidu.com")创建了一个ping百度的进程,并通过BufferedReader读取进程输出流并打印出来。最后输出"任务执行完毕!"表示进程执行结束。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [Java Process详解](https://blog.csdn.net/weixin_45433031/article/details/125327662)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值