Java如何执行操作系统的CMD命令行
在模拟cmd调用Python时遇到一些情况,这类问题可以归类为“超时,阻塞”等,问题原因:
Process p=Runtime.getRuntime().exec(String[] cmd);
Runtime.exec方法将产生一个本地的进程,并返回一个Process子类的实例,该实例可用于控制进程或取得进程的相关信息。 由于调用Runtime.exec方法所创建的子进程没有自己的终端或控制台,因此该子进程的标准IO(如stdin,stdou,stderr)都通过p.getOutputStream(),p.getInputStream(),p.getErrorStream() 方法重定向给它的父进程了.用户需要用这些stream来向子进程输入数据或获取子进程的输出。
例如:Runtime.getRuntime().exec("ls") 另外需要关心的是Runtime.getRuntime().exec()中产生停滞(阻塞,blocking)的问题? 这个是因为Runtime.getRuntime().exec()要自己去处理stdout和stderr的输出, 就是说,执行的结果不知道是现有错误输出(stderr),还是现有标准输出(stdout)。你无法判断到底那个先输出,所以可能无法读取输出,而一直阻塞。 例如:你先处理标准输出(stdout),但是处理的结果是先有错误输出(stderr), 一直在等错误输出(stderr)被取走了,才到标准输出(stdout),这样就产生了阻塞。
解决办法:
用两个线程将标准输出(stdout)和错误输出(stderr)。
完整代码:
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.InputStreamReader;
/**
* Create by yster@foxmail.com 2018/11/9 0009 22:28
*/
public class ExecuteCmd {
/**
* 执行外部程序,并获取标准输出
*/
public static String execute(String[] cmd,String... encoding) {
BufferedReader bufferedReader;
InputStreamReader inputStreamReader;
try {
Process p = Runtime.getRuntime().exec(cmd);
/* 为"错误输出流"单独开一个线程读取之,否则会造成标准输出流的阻塞 */
Thread t = new Thread(new InputStreamRunnable(p.getErrorStream(), "ErrorStream"));
t.start();
/* "标准输出流"就在当前方法中读取 */
BufferedInputStream bis = new BufferedInputStream(p.getInputStream());
if (encoding != null && encoding.length != 0) {
inputStreamReader = new InputStreamReader(bis, encoding[0]);// 设置编码方式
} else {
inputStreamReader = new InputStreamReader(bis, "utf-8");
}
bufferedReader = new BufferedReader(inputStreamReader);
StringBuilder sb = new StringBuilder();
String line;
while ((line = bufferedReader.readLine()) != null) {
sb.append(line);
sb.append("\n");
}
bufferedReader.close();
p.destroy();
return sb.toString();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
class InputStreamRunnable implements Runnable {
private BufferedReader bReader = null;
InputStreamRunnable(InputStream is, String type) {
try {
bReader = new BufferedReader(new InputStreamReader(new BufferedInputStream(is), "UTF-8"));
} catch (Exception ex) {
ex.printStackTrace();
}
}
public void run() {
String line;
int num = 1;
try {
while ((line = bReader.readLine()) != null) {
//System.out.println("---->"+String.format("%02d",num++)+" "+line);
}
bReader.close();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
Java如何执行操作系统的CMD命令行的更多相关文章
- 在cmd命令行使用Maven Archetype插件 generate命令创建简单的java web项目
前提: 1.下载apache-maven:https://mirrors.tuna.tsinghua.edu.cn/apache/maven/maven-3/3.3.9/binaries/apache ...
- 在windows下使用cmd命令行对java文件进行编译和执行
windows下利用cmd命令行可以调用jdk里的javac.exe和java.exe对java文件进行编译和执行,前提是jdk已成功安装并正确配置相关环境变量 相关配置链接:java基础学习总结—— ...
- paip.执行shell cmd 命令uapi java php python总结
paip.执行shell cmd 命令uapi java php python总结 作者Attilax 艾龙, EMAIL:1466519819@qq.com 来源:attilax的专栏 地址:h ...
- Atitit.执行cmd 命令行 php
Atitit.执行cmd 命令行 php 1. 执行cmd 命令行,调用系统命令的基础 1 1.1. 实际执行模式 1 1.2. 空格的问题 1 1.3. 中文路径的问题,程序文件读取编码设置 1 1 ...
- [Java] cmd命令行如何切换目录
cmd.exe是微软Windows系统基于WINDOWS上的命令解释程序,类似于微软的DOS操作系统.cmd.exe是一个32位的命令行程序,运行在Windows NT/2000/XP/2003/vi ...
- CMD命令行提示被禁用的情况下如何继续使用命令行工具执行命令
1.直接在Windows搜索 左下 输入要执行的 CMD 命令单句.多句同时执行没有试出来. 暂时记录这一条.2016-12-20
- Windows 如何在cmd命令行中查看、修改、删除与添加环境变量
转自:http://www.cnblogs.com/saptechnique/archive/2013/02/17/2914222.html 首先明确一点: 所有的在cmd命令行下对环境变量的修改只对 ...
- 如何在cmd命令行中查看、修改、删除与添加环境变量,语法格式例子:set path;echo %APPDATA%
如何在cmd命令行中查看.修改.删除与添加环境变量 首先明确一点: 所有的在cmd命令行下对环境变量的修改只对当前窗口有效,不是永久性的修改.也就是说当关闭此cmd命令行窗口后,将不再起作用.永久性修 ...
- cmd命令行带参启动程序
cmd命令行带参启动程序 有一些程序不支持被直接启动,编写代码时,我们可以通过Process类来启动某个进程(某个软件),在不用代码调从而启动某个软件时,windows系统下,通常我们会用到cmd命令 ...
随机推荐
- MVC中IActionFilter过滤器俄罗斯套娃的实现方式
看mvc的源码我们知道,它是在 ControllerActionInvoker 类中执行 InvokeAction 方法来实现过滤器和action方法执行的. 通过查看源码我们知道,他是通过调用 In ...
- swift(三)字典数组操作
//1.数组的概念和定义 var array = [,,,] var array1:Array = [,,,] var array2:Array<Int> = [,,,]; var arr ...
- ios 点击webview获取图片url (js交互)
加手势 -(void)handleSingleTap:(UITapGestureRecognizer *)sender { CGPoint pt = [sender locationInView:_c ...
- 019.nexus搭建docker镜像仓库/maven仓库
一.安装docker CE 参考docker doc https://docs.docker.com/install/linux/docker-ce/centos/ 二.docker启动nexus3 ...
- [基础]斯坦福cs231n课程视频笔记(三) 训练神经网络
目录 training Neural Network Activation function sigmoid ReLU Preprocessing Batch Normalization 权重初始化 ...
- C++编译错误 --- 成员函数定义在 .h 文件中出现重定义错误(Error LNK 2005)
今天写了一个简单的类,定义在 .h 文件中, 类很简单就将其成员函数定义在了一起(class类后面).运行的时候出现了如下图所示的编译错误(error LNK2005) 查资料,大部分都是说需要加上 ...
- 201871010105-曹玉中《面向对象程序设计(java)》第十六周学习总结
201871010105-曹玉中<面向对象程序设计(java)>第十六周学习总结 项目 内容 这个作业属于哪个过程 https://www.cnblogs.com/nwnu-daizh/ ...
- 201871010125-王玉江《面向对象程序设计(java)》第十五周学习总结
项目 内容 这个作业属于哪个课程 <任课教师博客主页链接> https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 <作业链接地址> ht ...
- 201871020225-牟星源《面向对象程序设计(java)》第七周学习总结
201871020225-牟星源<面向对象程序设计(java)>第七周学习总结 博文正文开头: 项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu- ...
- Lambda 表达式应用 权限管理_用户的角色修改
Lambda 表达式应用 权限管理_用户的角色修改 需求 前台发送用户新的角色列表,后台查询出用户原有的角色列表. 1.获取出需增加的角色列表 => 在新角色列表中,但是不在原角色列表中的角色 ...