世界时讯:Process类详解 相关类和方法介绍
Process类详解
一、相关类和方法介绍二、安全风险1. external processes block on I|O streams
一、相关类和方法介绍
(相关资料图)
ProcessBuilder是一个final类,Process是一个抽象类。ProcessBuilder.start()和 Runtime.exec()方法都被用来创建一个操作系统进程(执行命令行操作),并返回 Process子类的一个实例,该实例可用来控制进程状态并获得相关信息。
每个进程生成器ProcessBuilder对象管理这些进程属性:
命令 是一个字符串列表,它表示要调用的可执行外部程序文件及其参数(如果有)。环境 是从变量 到值 的依赖于系统的映射。工作目录 默认值是当前进程的当前工作目录,通常根据系统属性 user.dir 来命名。redirectErrorStream 属性 子进程的标准输出和错误输出是否被发送给发送给两个独立的流(Process.getInputStream() 和 Process.getErrorStream()),默认false发送。
Runtime.exec()可接受一个单独的字符串,这个字符串是通过空格来分隔可执行命令程序和参数的;也可以接受字符串数组参数/list。ProcessBuilder.start()只支持字符串数组参数。
创建的子进程没有自己的终端或控制台。它的所有标准 io(即 stdin,stdout,stderr)操作都将通过三个流(getOutputStream(),getInputStream(),getErrorStream()) 重定向到父进程。
// Runtime.exec最终是通过调用ProcessBuilder来真正执行操作的public Process exec(String[] cmdarray, String[] envp, File dir) throws IOException {// 在 directory() 指定的工作目录中,利用 environment() 指定的进程环境,新进程将调用由 command() 给出的命令和参数。 return new ProcessBuilder(cmdarray) .environment(envp) .directory(dir) .start();}
注意 ProcessBuilder 第一个参数必须是可执行程序,可以添加参数使用{"cmd", "/c"}或 {"/bin/bash", "-c"}。
二、安全风险
描述 java.lang.Process 对象描述进程可能需要通过其输入流对其提供输入,并且其输出流、错误流或两者同时会产生输出。不正确地处理这些外部程序可能会导致一些意外的异常、DoS,及其他安全问题。 一个进程如果试图从一个空的输入流中读取输入,则会一直阻塞,直到为其提供输入。因此,在调用这样的进程时,必须为其提供输入。 一个外部进程的输出可能会耗尽该进程输出流与错误流的缓冲区。当发生这种情况时,Java 程序可能会阻塞外部进程,同时阻碍Java程序与外部程序的继续运行。因此,在运行一个外部进程时,如果此进程往其输出流发送任何数据,则必须将其输出流清空。类似的,如果进程会往其错误流发送数据,其错误流也必须被清空。
处理建议 对于那些从来不会读取其输入流的进程,不对其提供输入非但无害,且还有益。而对于那些从来不会发送数据到其输出流或者错误流的进程,不对其输出流或者错误流进行清空同样是有益无害的。因此,只要能够保证进程不会使用这些流,那么在程序中可以忽略其输入流、输出流、以及错误流。
1. external processes block on I|O streams
原因 有些本机平台仅针对标准输入和输出流提供有限的=缓冲区大小,如果读写子进程的输出流或输入流迅速出现失败(如不断发送数据),而主进程调用Process.waitfor后已挂起,则可能导致子进程阻塞,进程间相互等待甚至产生死锁。
现有如下三种解决方法,缓冲区内容消费掉即可。
// Do not let external processes block on I|O streams// 场景一: 使用java.lang.ProcessBuilder.redirectErrorStream(boolean redirectErrorStream)方法即可清空流ProcessBuilder builder = new ProcessBuilder(cmds);builder.redirectErrorStream(true);try {process = builder.start();} catch (IOException e) {e.pringtStackTrace();}// 场景二:当出现IOException异常时不应该将IOException异常throws,使用try/catch对IOException单独捕获Process process = null;try {process = builder.start();} catch (IOException e) {e.pringtStackTrace();}String handleMessage = "";BufferedReader bufferedReader = new BufferedSReader(new InputStreamReader(process.getInputStream, StandardCharesets.UTF_8));try {while ((handleMessage = bufferedReader.readLine()) != null) {System.out.println(handleMessage);}} catch (IOException e) {e.pringtStackTrace();}try {bufferedReader.close();} catch (IOException e) {e.pringtStackTrace();}// 场景三:有时候我们可能需要调用系统外部的某个程序,此时就可以用Runtime.getRuntime().exec()来调用,他会生成一个新的进程去运行调用的程序,waitFor()方法也有很明显的弊端,因为java程序给进程的输出流分配的缓冲区是很小的,有时候当进程输出信息很大的时候回导致缓冲区被填满,如果不及时处理程序会阻塞,解决的方法就是处理缓冲区中的信息,开两个线程分别去处理标准输出流和错误输出流Process process = Runtime.getRuntime().exec(str);// 记录进程缓存错误信息final StringBuffer errorLog = new StringBuffer();final InputStream errorStream = process.getErrorStream();final InputStream inputStream = process.getInputStream();// 处理InputStream的线程new Thread() {@Override public void run() {BufferedReader in = new BufferedReader(new InputStreamReader(inputStream)); String line = null; try {// 消费掉缓存中的数据 while ((line = in.readLine()) != null && !errorLog.toString().contains("ERROR")) {if (line != null) {errorLog.append(line); } } } catch (IOException e) {// public RuntimeException(String message, Throwable cause) throw new RuntimeException("[shell exec error]:" + errorLog, e); } finally {try {inputStream.close();; } catch (IOException e) {e.printStackTrace(); } } }}.start();// 处理errorStream的线程new Thread() {@Override public void run() {BufferedReader err = new BufferedReader(new InputStreamReader(errorStream)); String line = null; try {// 消费掉缓存中的数据 while ((line = err.readLine()) != null && !errorLog.toString().contains("ERROR")) {if (line != null) {errorLog.append(line); } } } catch (IOException e) {throw new RuntimeException("[shell exec error]:" + errorLog, e); } finally {try {errorStream.close();; } catch (IOException e) {e.printStackTrace(); } } }}.start();logger.info("等待shell脚本执行完成");Thread.sleep(1000);// 异常终止if (errorLog != null && errorLog.length() > 0 && errorLog.toString().contains("ERROR")) {dispatchLogger.error("[shell exec error]:" + errorLog); throw new RuntimeException("[shell exec error]:" + errorLog);}// 等待shell脚本执行完成process.waitFor();
标签:
相关推荐:
最新新闻:
- 云课堂智慧职教网页版登录入口 智慧职教云课堂怎么登录?
- DHCP协议简介 DHCP三种分配方式
- 全球实时:setTimeout是什么意思?彻底理解setTimeout
- 数据显示:2021年国内应用商店在线App数量减少21.4%
- Java中的BigDecimal类使用 三种类型的构造方法
- 世界时讯:Process类详解 相关类和方法介绍
- 今日热搜:Volatile详解 现代计算机的内存模型的详情介绍
- Scope参数错误或没有Scope权限怎么办?解决办法
- security是什么意思?security详解-即时看
- 【环球聚看点】蕾哈娜抖音首次晒娃:这表情 确定是亲生的!
- JavaScript简介 弱类型语言详情介绍
- 什么是域?AD域的详细介绍
- 手游《古惑狼:全速冲锋》将停服 发售不到2年|焦点速递
- 读书郎学生电脑如何下载?读书郎电脑下载步骤
- 京东联盟/好京客API与京东默认PID申请教程 京东API注册测试账号
- Ubuntu中snap是什么意思?介绍一些常用命令|焦点播报
- LOL各英雄的原型来源你了解几个? LOL背后的小故事
- 如何在excel中画斜线?在excel中画斜线的方法|天天新消息
- 激光焊接机价格怎么样?激光焊接机价格参考_世界滚动
- 全球滚动:电烤箱烤羊肉串怎么做?电烤箱烤羊肉串做法步骤
- sd卡数据恢复软件有哪些?sd卡数据恢复的软件
- 手机多媒体没声音是怎么回事?手机多媒体没声音怎么修?
- ISO9000和ISO9001有什么特点?ISO9000和ISO9001作用详解_环球头条
- 抖音可以查访客记录吗?抖音访客记录怎么看?
- 当前焦点!DOTA2前EG队长Fly求婚成功 晒出甜蜜合影
- 小键盘指法怎么操作?小键盘指法练习技巧|当前快播
- Windows 11壁纸有新玩法 用户可以自己画 焦点简讯
- 手机闪存卡哪款好?经典手机闪存卡有哪些推荐?|信息
- 电阻式触摸屏好用吗?电阻式触摸屏工作原理|全球信息
- 人生中的第一个Java程序:HelloWorld:天天百事通
- 爱宁牌电饼铛怎样?爱宁牌电饼铛的优势介绍
- vice versa是什么意思?vice versa通常翻译 世界快播
- 《冷漠 鸣神学园的七大不可思议》大型DLC12月23日上线
- 视讯!文件删除了怎么恢复?文件删除了三种恢复方法
- 联想服务器linux系统raid驱动 IntelRAID 6.12版RAID卡驱动官方正式版下载
- 全球快看点丨这款国产操作系统界面竟与Windows 11如出一辙
- 【环球快播报】除了币安,币圈最危险的大麻烦:稳定币USDT
- 浏览器市场占有率排行表 2020年8月国内浏览器排行
- GSC将推出上坂堇可动手办:声优首次figma化!
- 笔记本电脑品牌有哪些推荐?五款热门品牌推荐-焦点滚动
- 英特尔发力 游戏本将迎来24核心处理器-即时看
- 焦点速看:有哪些好看的电影推荐?吐血推荐250部必看电影
- 看热讯:华为荣耀4C详细评测 再次刷新安卓手机性价比
- 节能灯具有哪些品牌?节能灯具品牌介绍
- 苹果手机助手哪个好?推荐几款好用的苹果手机助手:世界今热点
- 磊科升级版NW360怎么样?磊科升级版NW360详细介绍-动态焦点
- RX 7900系列开卖被秒光 诸多用户回归N卡阵营:环球速看料
- 如何打开关闭Excel2007/2010兼容性检查器?关闭技巧:全球要闻
- 炉石传说美服天梯第一的冠军贼卡组分享 详细介绍 当前热点
- hr是什么意思?管理的五大原则|全球聚看点
- 看热讯:华为荣耀4C详细评测 再次刷新安卓手机性价比
- 世界热点!计算机拨号连接无法建立连接怎么办?电信拨号上网连接不上的解决方法
- E. Border是什么?拓展欧几里得+mod分析
- 520还在画玫瑰?教你用MATLAB画个玫瑰花球|实时焦点
- 热门看点:币安将以10.22亿美元的价格收购加密货币借贷平台Voyager的资产
- IPO大潮退去,美股繁盛时期上市的大批股票现在面临退市风险
- 卡梅隆封神往事:一个天才疯子和《阿凡达》的20年_世界实时
- 神谷英树将《猎天使魔女:起源》比作童心绘本-全球播报
- Steam喜加一:圣诞主题像素排球游戏《Jollyball》
- 《碟中谍7》官方幕后花絮:阿汤哥太拼 3000米飞车跳崖|全球快播报
- 联想USB 3.0扩展坞29元限时秒:4个USB接口 支持Type-C供电-世界热点
- 苹果新一代显示器来了:屏幕升级为mini LED
- NVIDIA CES新品发布会官宣:RTX 4070 Ti、RTX 40笔记本显卡要来了:热门看点
- 性价比还得看AMD 6核锐龙+显卡+主板套装1239元:当前要闻
- 环球快消息!ZOL科技早餐:骁龙8 Gen2新机2999元,魅族19外观将揭晓
- 《水浒风云传》确定12月22日登陆Xbox和Switch 天天观速讯
- 【天天新视野】《原神》剧情视频「秋津羽戏」讲述人与妖的友情
- 高手用虚幻5做出《刺客信条》粉丝最期待的游戏功能
- 96核心192线程!AMD Zen4线程撕裂者7000将至 当前速递
- 冬日特别福利!即刻上手领取你的穿越火线限定礼包吧:今日热讯
- 环球时讯:CES 2023 多家电脑厂商预热新款大屏游戏本
- 三强联手:Steam与苹果正式加盟特斯拉_天天短讯
- 马斯克狂卖特斯拉股票:三天套现250+亿人民币
- 姆巴佩决赛失利首度发声:我们会回来的! 每日观点
- 【世界独家】艰难的阿根廷,比梅西更需要这座大力神杯