此类用于创建操作系统进程。
每个
ProcessBuilder
实例管理一组进程属性。
start()
方法使用这些属性创建新的
Process
实例。
可以从同一实例重复调用
start()
方法,以创建具有相同或相关属性的新子
进程
。
可以调用
startPipeline
方法来创建新进程的管道,将每个进程的输出直接发送到下一个进程。
每个进程都具有其各自ProcessBuilder的属性。
每个流程构建器都管理这些流程属性
一个
命令
,一个字符串列表,表示要调用的外部程序文件及其参数(如果有)。
哪个字符串列表表示有效的操作系统命令取决于系统。
例如,每个概念参数通常都是此列表中的元素,但是有些操作系统需要程序对命令行字符串本身进行标记 - 在这样的系统上,Java实现可能需要命令才能包含两个元素。
环境
,是从
变量
到
值
的系统相关映射。
初始值是当前进程的环境副本(请参阅
System.getenv()
)。
一个
工作目录
。
默认值是当前进程的当前工作目录,通常是系统属性
user.dir
指定的目录。
a source of
standard input
。
默认情况下,子进程从管道读取输入。
Java代码可以通过
Process.getOutputStream()
返回的输出流访问此管道。
但是,可以使用
redirectInput
将标准输入重定向到另一个源。
在这种情况下,
Process.getOutputStream()
将返回一个
空输出流
,其中:
write
方法总是抛出
IOException
close
方法什么都不做
a destination for
standard output
and
standard error
。
默认情况下,子进程将标准输出和标准错误写入管道。
Java代码可以通过
Process.getOutputStream()
和
Process.getErrorStream()
返回的输入流访问这些管道。
但是,可以使用
redirectOutput
和
redirectError
将标准输出和标准错误重定向到其他目标。
在这种情况下,
Process.getInputStream()
和/或
Process.getErrorStream()
将返回
空输入流
,其中:
read
方法始终返回
-1
available
方法始终返回
0
close
方法什么都不做
redirectErrorStream
属性。
最初,此属性为
false
,这意味着子
false
的标准输出和错误输出将发送到两个单独的流,可以使用
Process.getInputStream()
和
Process.getErrorStream()
方法访问这些流。
如果该值设置为
true
,则:
标准错误与标准输出合并,并始终发送到同一目标(这使得更容易将错误消息与相应的输出相关联)
可以使用
redirectOutput
重定向标准错误和标准输出的公共目标
创建子
进程
时,将忽略
redirectError
方法设置的任何重定向
从
Process.getErrorStream()
返回的流将始终是
null input stream
修改流程构建器的属性将影响随后由该对象的
start()
方法启动的流程,但绝不会影响以前启动的流程或Java流程本身。
大多数错误检查由
start()
方法执行。
可以修改对象的状态,以便
start()
失败。
例如,将命令属性设置为空列表不会抛出异常,除非调用
start()
。
请注意,此类未同步。
如果多个线程同时访问
ProcessBuilder
实例,并且至少有一个线程在结构上修改其中一个属性,则
必须
在外部进行同步。
启动使用默认工作目录和环境的新进程很简单:
Process p = new ProcessBuilder("myCommand", "myArg").start();
下面是一个使用修改的工作目录和环境启动进程的示例,并将标准输出和错误重定向到日志文件中:
ProcessBuilder pb = new ProcessBuilder("myCommand", "myArg1", "myArg2"); Map<String, String> env = pb.environment(); env.put("VAR1", "myValue"); env.remove("OTHERVAR"); env.put("VAR2", env.get("VAR1") + "suffix"); pb.directory(new File("myDir")); File log = new File("log"); pb.redirectErrorStream(true); pb.redirectOutput(Redirect.appendTo(log)); Process p = pb.start(); assert pb.redirectInput() == Redirect.PIPE; assert pb.redirectOutput().file() == log; assert p.getInputStream().read() == -1;
要使用一组显式环境变量启动进程,请在添加环境变量之前先调用
Map.clear()
。
除非另有说明,否则将
null
参数传递给
null
中的构造函数或方法将导致抛出
NullPointerException
。
从以下版本开始:
返回此流程构建器环境的字符串映射视图。
无论何时创建流程构建器,环境都将初始化为当前流程环境的副本(请参阅
System.getenv()
)。
随后由此对象启动的子进程的
start()
方法将使用此映射作为其环境。
可以使用普通的
Map
操作修改返回的对象。
通过
start()
方法启动的子过程可以看到这些修改。
两个
ProcessBuilder
实例始终包含独立的进程环境,因此对返回的映射的更改将永远不会反映在任何其他
ProcessBuilder
实例或
System.getenv
返回的值中。
如果系统不支持环境变量,则返回空映射。
返回的映射不允许空键或值。
尝试插入或查询是否存在空键或值将引发
NullPointerException
。
试图查询不是
String
类型的键或值的存在将抛出
ClassCastException
。
返回的映射的行为取决于系统。
系统可能不允许修改环境变量或禁止某些变量名称或值。
因此,如果操作系统不允许修改,则尝试修改映射可能会失败,如
UnsupportedOperationException
或
IllegalArgumentException
。
由于环境变量名称和值的外部格式与系统有关,因此它们与Java的Unicode字符串之间可能没有一对一的映射。
然而,映射的实现方式是,未被Java代码修改的环境变量在子进程中将具有未修改的本机表示。
返回的地图及其集合视图可能不遵守
Object.equals(java.lang.Object)
和
Object.hashCode()
方法的一般合同。
返回的映射通常在所有平台上都区分大小写。
如果存在安全管理器,则使用
RuntimePermission
("getenv.*")
权限调用其
checkPermission
方法。
这可能会导致抛出
SecurityException
。
将信息传递给Java子
进程时
,
system properties
通常优先于环境变量。
这个流程构建器的环境
SecurityException
- 如果存在安全管理器且其
checkPermission
方法不允许访问进程环境
另请参见:
Runtime.exec(String[],String[],java.io.File)
,
System.getenv()
redirectInput
public ProcessBuilder redirectInput(ProcessBuilder.Redirect source)
设置此流程构建器的标准输入源。
随后由此对象的
start()
方法启动的子
进程
从此源获取其标准输入。
如果源是
Redirect.PIPE
(初始值),则可以使用
Process.getOutputStream()
返回的输出流写入子
进程
的标准输入。
如果源设置为任何其他值,则
Process.getOutputStream()
将返回
null output stream
。
source
- 新的标准输入源
这个流程构建器
IllegalArgumentException
- 如果重定向与有效数据源不对应,即类型为
WRITE
或
APPEND
从以下版本开始:
redirectOutput
public ProcessBuilder redirectOutput(ProcessBuilder.Redirect destination)
设置此流程构建器的标准输出目标。
随后由此对象的
start()
方法启动的子
进程
将其标准输出发送到此目标。
如果目标是
Redirect.PIPE
(初始值),则可以使用
Process.getInputStream()
返回的输入流读取子
进程
的标准输出。
如果目标设置为任何其他值,则
Process.getInputStream()
将返回
null input stream
。
destination
- 新标准输出目标
这个流程构建器
IllegalArgumentException
- 如果重定向与数据的有效目标不对应,即类型为
从以下版本开始:
redirectError
public ProcessBuilder redirectError(ProcessBuilder.Redirect destination)
设置此进程生成器的标准错误目标。
随后由此对象的
start()
方法启动的子
进程
将其标准错误发送到此目标。
如果目标是
Redirect.PIPE
(初始值),则可以使用
Process.getErrorStream()
返回的输入流读取子
进程
的错误输出。
如果目标设置为任何其他值,则
Process.getErrorStream()
将返回
null input stream
。
如果
已将
redirectErrorStream
属性设置为
true
,则此方法设置的重定向无效。
destination
- 新的标准错误目标
这个流程构建器
IllegalArgumentException
- 如果重定向与数据的有效目标不对应,即类型为
从以下版本开始:
pb.inheritIO()
行为与调用完全相同
pb.redirectInput(Redirect.INHERIT) .redirectOutput(Redirect.INHERIT) .redirectError(Redirect.INHERIT)
这提供了与大多数操作系统命令解释程序或标准C库函数
system()
。
这个流程构建器
从以下版本开始:
redirectErrorStream
public ProcessBuilder redirectErrorStream(boolean redirectErrorStream)
设置此进程生成器的
redirectErrorStream
属性。
如果此属性为
true
,则此对象的
start()
方法随后启动的子
true
生成的任何错误输出都将与标准输出合并,以便可以使用
Process.getInputStream()
方法读取这两个
错误
。
这样可以更容易地将错误消息与相应的输出相关联。
初始值为
false
。
redirectErrorStream
- 新属性值
这个流程构建器
使用此流程构建器的属性启动新流程。
新进程将调用由指定的命令和参数
command()
按以下给出,在工作目录
directory()
,有一个过程的环境被给出
environment()
。
此方法检查该命令是否是有效的操作系统命令。
哪些命令有效取决于系统,但至少该命令必须是非空字符串的非空列表。
在某些操作系统上启动进程可能需要一组最小的系统相关环境变量。
因此,子进程可以继承除进程构建器
environment()
之外的其他环境变量设置。
如果有安全管理器,则调用其
checkExec
方法,并将此对象的
command
数组的第一个组件作为其参数。
这可能导致抛出
SecurityException
。
启动操作系统进程高度依赖于系统。
在许多可能出错的事情中:
找不到操作系统程序文件。
访问程序文件被拒绝。
工作目录不存在。
命令参数中的字符无效,例如NUL。
在这种情况下,将抛出异常。
异常的确切性质取决于系统,但它始终是
IOException
的子类。
如果操作系统不支持创建进程,则将抛出
UnsupportedOperationException
。
对此流程构建器的后续修改不会影响返回的
Process
。
用于管理子
进程
的新对象
Process
NullPointerException
- 如果命令列表的元素为null
IndexOutOfBoundsException
- 如果该命令是空列表(大小为
SecurityException
- 如果存在安全管理器并且
其
checkExec
方法不允许创建子
进程
,或
子
进程
的标准输入是
redirected from a file
,安全管理器的
checkRead
方法拒绝对文件的读访问,或者
子
进程
的标准输出或标准错误是
redirected to a file
,安全管理器的
checkWrite
方法拒绝对文件的写访问
UnsupportedOperationException
- 如果操作系统不支持创建进程。
IOException
- 如果发生I / O错误
另请参见:
Runtime.exec(String[], String[], java.io.File)
startPipeline
public static List<Process> startPipeline(List<ProcessBuilder> builders)
throws IOException
为每个ProcessBuilder启动一个Process,创建一个由标准输出和标准输入流链接的流程管道。
每个ProcessBuilder的属性用于启动相应的进程,除了每个进程启动时,其标准输出将定向到下一个进程的标准输入。
使用相应ProcessBuilder的重定向设置初始化第一个进程的标准输入和最后一个进程的标准输出的重定向。
所有其他
ProcessBuilder
重定向应为
Redirect.PIPE
。
无法访问中间进程之间的所有输入和输出流。
除第一个进程外的所有进程的
standard input
都是
空输出流
除了最后一个进程之外的所有进程的
standard output
都是
空输入流
。
每个ProcessBuilder的
redirectErrorStream()
适用于相应的流程。
如果设置为
true
,则错误流将写入与标准输出相同的流。
如果启动任何进程抛出异常,则强制销毁所有进程。
该
startPipeline
方法一样的每个的ProcessBuilder执行相同的检查
start()
方法。
新进程将调用由指定的命令和参数
command()
按以下给出,在工作目录
directory()
,有一个过程的环境被给出
environment()
。
此方法检查该命令是否是有效的操作系统命令。
哪些命令有效取决于系统,但至少该命令必须是非空字符串的非空列表。
在某些操作系统上启动进程可能需要一组最小的系统相关环境变量。
因此,子进程可以继承除进程构建器
environment()
之外的其他环境变量设置。
如果有安全管理器,则调用其
checkExec
方法,并将此对象的
command
数组的第一个组件作为其参数。
这可能导致抛出
SecurityException
。
启动操作系统进程高度依赖于系统。
在许多可能出错的事情中:
找不到操作系统程序文件。
访问程序文件被拒绝。
工作目录不存在。
命令参数中的字符无效,例如NUL。
在这种情况下,将抛出异常。
异常的确切性质取决于系统,但它始终是
IOException
的子类。
如果操作系统不支持创建进程,则会抛出
UnsupportedOperationException
。
对此流程构建器的后续修改不会影响返回的
Process
。
API Note:
例如,要计算Unix兼容平台上文件层次结构中所有文件的唯一导入:
String directory = "/home/duke/src"; ProcessBuilder[] builders = { new ProcessBuilder("find", directory, "-type", "f"), new ProcessBuilder("xargs", "grep", "-h", "^import "), new ProcessBuilder("awk", "{print $2;}"), new ProcessBuilder("sort", "-u")}; List<Process> processes = ProcessBuilder.startPipeline( Arrays.asList(builders)); Process last = processes.get(processes.size()-1); try (InputStream is = last.getInputStream(); Reader isr = new InputStreamReader(is); BufferedReader r = new BufferedReader(isr)) { long count = r.lines().count(); }
builders
- ProcessBuilders列表
List<Process>
es从相应的ProcessBuilder开始
IllegalArgumentException
- 除第一个构建器的标准输入和最后一个构建器的标准输出之外的任何重定向都不是
ProcessBuilder.Redirect.PIPE
。
NullPointerException
- 如果命令列表的元素为null或者ProcessBuilder列表的元素为null或者builders参数为null
IndexOutOfBoundsException
- 如果该命令是空列表(大小为
SecurityException
- 如果存在安全管理器并且
其
checkExec
方法不允许创建子
进程
,或
子
进程
的标准输入是
redirected from a file
,安全管理器的
checkRead
方法拒绝对文件的读访问,或者
子
进程
的标准输出或标准错误是
redirected to a file
,安全管理器的
checkWrite
方法拒绝对文件的写访问
UnsupportedOperationException
- 如果操作系统不支持创建进程
IOException
- 如果发生I / O错误
从以下版本开始: