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命令 ...
随机推荐
- Ext学习之路——Ext.application
Ext.application({ name: 'MyApp', launch: function() { Ext.create('Ext.container.Viewport', { items: ...
- SAP MM MIGO过账报错 - 用本币计算的余额 - 之对策
SAP MM MIGO过账报错 - 用本币计算的余额 - 之对策 使用MIGO事务代码对采购订单4500000191,执行收货,系统报错: 详细错误信息如下: 用本币计算的余额 消息号 F5703 诊 ...
- SpringBoot使用Swagger2构建API文档
后端开发中经常需要对移动客户端提供RESTful API接口,在后期版本快速迭代的过程中,修改接口实现的时候都必须同步修改接口文档,而文档与代码又处于两个不同的媒介,除非有严格的管理机制,不然很容易导 ...
- jersey实现RESTful接口PUT方法JSON数据传递
项目中使用的是org.json包 maven中的配置如下: xml <!-- https://mvnrepository.com/artifact/org.json/json --> &l ...
- Rust的多线程程序
一定要用闭包? 感觉有点过了. use std::thread; use std::time::Duration; fn main() { let v = vec![, , ]; let handle ...
- 09-webpack--配置less
<!-- cnpm i less-loader less -D 要下载两个 在入口文件main.js文件中引入 import './css/index.less' webpack.config. ...
- Linux sh、source和.命令执行.sh文件的区别
sh文件介绍 .sh为Linux的脚本文件,我们可以通过.sh执行一些命令,可以理解为windows的.bat批处理文件. 点命令 .命令和source是同一个命令,可以理解为source的缩写,简称 ...
- Gson:
- luoguP1829 [国家集训队]Crash的数字表格 / JZPTAB(莫比乌斯反演)
题意 注:默认\(n\leqslant m\). 所求即为:\(\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{m}lcm(i,j)\) 因为\(i*j=\gcd(i, ...
- Linux文件系统与日志
1.inode 包含文件的元信息(1)inode 内容:文件的字节数.拥有者的 UID.GID.文件的读写执行权限.时间戳等,但不包含文件名.文件名是储存在目录的目录项中.(2)查看文件的 inode ...