java调用process 有两种实现方法,一是使用Runtime类,二是使用Process类。

我在最近的项目里用的是Runtime类,接下来写下总结。

有图有真相(在网上学来一句话)


 package com.lee.demo;

 import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader; public class RuntimeDemo01 { public static void main(String[] args) {
String s;
StringBuilder sb = new StringBuilder();
InputStream fis = null;
try {
// Process process = Runtime.getRuntime().exec("ping localhost");
Process process = Runtime.getRuntime().exec(new String[]{"sh", "-c", XXXX});
// 注意,我将原来的15行注释掉了,变成了下面的写法。声明,我调用的command是Lunix下的命令,如果你用的是windows的话,不需要这么写。
// 为什么要使用这样的写法,因为项目需要考虑到单引号双引号等,转换加/的原因。
fis = process.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(fis));
while((s=bufferedReader.readLine()) != null) {
sb.append(s);
//sb.append(\n);
}
System.out.println(sb.toString());
process.waitFor();
System.out.println(process.exitValue());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

执行结果如下

使用法: ping [-t] [-a] [-n 要求数] [-l サイズ] [-f] [-i TTL] [-v TOS]            [-r ホップ数] [-s ホップ数] [[-j ホスト一覧] | [-k ホスト一覧]]            [-w タイムアウト] [-R] [-S ソースアドレス] [-4] [-6] ターゲット名オプション:    -t             中断されるまで、指定されたホストを Ping します。                   統計を表示して続行するには、Ctrl+Break を押してください。                   停止するには、Ctrl+C を押してください。    -a             アドレスをホスト名に解決します。    -n 要求数      送信するエコー要求の数です。    -l サイズ      送信バッファーのサイズです。    -f             パケット内の Don't Fragment フラグを設定します (IPv4 のみ)。    -i TTL         Time To Live です。    -v TOS         Type Of Service (IPv4 のみ。この設定はもう使用されておらず、                   IP ヘッダー内のサービス フィールドの種類に影響しません)。    -r ホップ数    指定したホップ数のルートを記録します (IPv4 のみ)。    -s ホップ数    指定したホップ数のタイムスタンプを表示します (IPv4 のみ)。    -j ホスト一覧  一覧で指定された緩やかなソース ルートを使用します                   (IPv4 のみ)。    -k ホスト一覧  一覧で指定された厳密なソース ルートを使用します                   (IPv4 のみ)。    -w タイムアウト                   応答を待つタイムアウトの時間 (ミリ秒) です。    -R             ルーティング ヘッダーを使用して逆ルートもテストします                   (IPv6 のみ)。    -S ソースアドレス                   使用するソース アドレスです。    -4             IPv4 の使用を強制します。    -6             IPv6 の使用を強制します。

如果你执行的命令是 ping localhost的话,那么是可以正常执行并返回黑屏下一样的结果的。

在这里说一下我遇到的几个坑。

首先,lunix下执行和windows下执行不一样。比如上面的例子中,ping这个命令,没有添加参数时,在执行结果中会打出黑屏下一样的提示信息,但是lunix下不行,在程序中需要process.getErrorStream(),这样才能得到一致的结果。

第二个坑,是要记得添加process.waitFor();这行代码,代码的意思是 线程一直到process结束再往下执行。如果不写这行代码,那么process执行的同时,线程在往下执行,到后面23行的代码会抛出error。此外,process.waitFor()代码要放在,对输入流的操作之后,因为每次输入流读取的大小是有限制的,如果超过最大值,而输入流中的内容没有被读取,那么久会发生阻塞,到时程序一直停在那里。

第三个坑,在上文中代码的第17行里,使用了匿名类的new InputStreamReader,在性能测试的时候,报错,can not open too many files,原因是InputStreamReader使用了之后,最后没有将他close。一定要在finally中将它close掉。

第四个坑,代码第18行,readLine()方法,大家很熟悉。我们看一下API中的定义。

public String readLine()
throws IOException Reads a line of text. A line is considered to be terminated by any one of a line feed ('\n'), a carriage return ('\r'), or a carriage return followed immediately by a linefeed. Returns:
A String containing the contents of the line, not including any line-termination characters, or null if the end of the stream has been reached
Throws:
IOException - If an I/O error occurs

在returns中,明确写明,只返回内容,不会返回换行符号等。这就导致最后我们取得的内容是一行String,很长。我决定在19行后,加个换行符,这样就可以换行了。

接下来,简单说明一下Process类,要说的是,自jdk1.5起,官方建议,使用ProcessBuilder.start()来启动process

官方文档地址: https://docs.oracle.com/javase/8/docs/api/java/lang/Process.html

其实JDK中Runtime最终调用的是processbuilder。

processbuilder提供的功能更加丰富,可以设置工作目录,环境变量等。

推荐一篇文章,processBuilder介绍得很好。

http://www.cnblogs.com/taven/archive/2011/12/17/2291460.html

java 调用process的更多相关文章

  1. java调用第三方命令,process.waitfor()挂起(你不知道的坑)

    我们常在java中运行第三方程序,如sh.python,java提供一个Runtime.exec()方法,生成一个Process对象.今天在使用这个方法的时候,发现接口半天没有返回数据.查了一下,原来 ...

  2. java调用mysql服务做备份与恢复

    首先添加mysql的bin到环境变量,这样可以简写部分命令,并且做到不依赖系统mysql的具体安装路径. 重启计算机可以让添加的环境变量在java代码中调用时生效.(cmd中生效但java中调用没有生 ...

  3. java调用shell获取返回值

    转自:http://blog.csdn.net/tengdazhang770960436/article/details/12014839 1.shell文件return.sh echo 1 echo ...

  4. Java调用ffmepg+mencoder视频格式转换(*)

    PS: 建议大家在官网下载最新的资源 其他格式转FLV格式,可以用Java调用ffmpeg和memcoder实现 ffmepg: D:\ffmpeg\bin\ffmpeg.exe -i E:\1.mp ...

  5. 关于java调用linux shell 的问题

    问题的提出: shell脚本要做离线的数据处理任务 java调用脚本,将这种处理任务封装成webservice 特点: shell处理单个时间长 每次要处理文件量大 这里目前只做调用分析: 原来的: ...

  6. java 调用 phantomjs

    java 调用 phantomjs 2014-11-21 13:55 2034人阅读 评论(2) 收藏 举报  分类: phantomjs(2)  日前有采集需求,当我把所有的对应页面的链接都拿到手, ...

  7. java调用phantomjs采集ajax加载生成的网页

    java调用phantomjs采集ajax加载生成的网页 日前有采集需求,当我把所有的对应页面的链接都拿到手,准备开始根据链接去采集(写爬虫爬取)对应的终端页的时候,发觉用程序获取到的数据根本没有对应 ...

  8. java 调用bash shell脚本阻塞的小问题的解决

    java  调用bash shell脚本阻塞的小问题的解决 背景 使用java实现的web端,web端相应用户的界面操作,使用java调用bash实现的shell脚本进行实际的操作,操作完成返回执行结 ...

  9. Java调用外部程序常用算法和封装类

    一个项目不可能只使用一种编程语言来开发,也不可能由一个人开发,所以,Java程序员要学会和使用其他编程语言的程序员合作.那么,让我来发布一个工具类--Java外接程序扩展包,并将相应算法发布.Java ...

随机推荐

  1. mysql 下载资源地址

    http://mirror.neu.edu.cn/mysql/Downloads/MySQL-5.6/

  2. Android Studio2.1版本后使用虚拟机碰见的问题总结以及其他问题

    一.androidstudio的sdk配置问题 如果点击Start a new Android Studio project是没有反应的,并且在Configure下面的SDK Manager是灰色的, ...

  3. lubuntu16.04 安装过程以及ssd测试模型的环境配置

    1.系统启动盘(ultraISO)制作启动盘, 1/5 文件->打开,打开我们的iso镜像 2/5 选择我们的u盘, 3/5 点击启动->写入硬盘映像 4/5 写入方式选择raw,格式化然 ...

  4. 怎样关掉 ubuntu 中的 System Program Problem Detected 提示框

    怎样关掉 ubuntu 中的 System Program Problem Detected 提示框 方法如下:sudo gedit /etc/default/apport  打开该文件如下:# se ...

  5. Zabbix4.0添加端口和进程监控

    一:Zabbix设置主动模式: vim /etc/zabbix/zabbix_agent.conf Server=192.168.1.10 #被动模式的serverip地址,如果设置纯被动模式,可以注 ...

  6. kubernetes 环境搭建(ubuntu16.04)

    通过kubeadm安装kubernetes的教程:1: 首先在每台机器上安装: docker(1.12), kubeadm(1.6), kubectl, kubelet, kubernetes-cni ...

  7. L314 单音节词读音规则(二)-元音字母发音规则

    1 单个元音发音尽量拖音一下(2S),发音会饱满一些. 2开音节: 辅音(辅组)(没有)+元音+辅音+e 的单词其中:元音发字母本身音,辅音字母不为r , 字母e不发音. 相对开音节:第一个元音都发字 ...

  8. rgba 和 opacity 的对比.

    rgba 中 的 a  指的是透明度: 1. rgba 的 设置的 透明度 不会被子级 元素继承;    opacity 设置的透明度会被子级元素继承 . 因此 ,有时候 使用 rgba 会比 opa ...

  9. ChinaCock界面控件介绍-TCCYearMonthSelector

    Delphi原生控件支持日期的选择,但对于只选择年月的情况,则没有好的实现.TCCYearMonthSelector正是为解决这个问题而产生的.看看运行效果图: 用法一如即往的简单,这是一个不可视控件 ...

  10. sql 按字段指定值排序

    这个需要在排序语句中使用条件判断 例如:表[Table_temp]中列[col1]为字符,属性为varchar(10),排序时需要按照B.A.C的顺序显示,则可按照以下SQL语句: select * ...