Jdk源码详解之ProcessBuilder()
类
1.ProcessBuilder类
2.方法简介
- 构造器ProcessBuilder
/**
Constructs a process builder with the specified operating
system program and arguments.
使用指定的操作系统以及参数构建一个process builder。
This is a convenience constructor that sets the process builder's command
to a string list containing the same strings as the {@code command}
array, in the same order.
这是一个方便的构造器,将process builder的命令转换成一个字符串列表,
这个字符串列表与command 数组有着相同的字符串,同样,其顺序也相同。
It is not checked whether command corresponds to a valid operating system
command.
这个是不被检查的:不管命令是否与操作系统相对应。
@param command a string array containing the program and its arguments
参数:command :一个包含程序以及该程序所需参数字符串数组
*/
public ProcessBuilder(String... command) {
this.command = new ArrayList<>(command.length);
for (String arg : command)
this.command.add(arg);
}
start()
方法
/**
Starts a new process using the attributes of this process builder.
使用这个process builder的属性开始一个新的进程
The new process will invoke the command and arguments given by command(),
in a working directory as given by #directory(),
with a process environment as given by #environment().
这个新的process将会调用由command()给出的命令以及参数,
在directory()给出的一个工作目录给,
以及environment()给出的一个process环境。
This method checks that the command is a valid operating
system command. Which commands are valid is system-dependent,
but at the very least the command must be a non-empty list of
non-null strings.
这个方法检测命令是一个有效的操作系统命令。哪些命令是有效的,这取决于依赖的系统,
但是至少,命令必须得是一个非空,非null的字符串。
<p>A minimal set of system dependent environment variables may
be required to start a process on some operating systems.
As a result, the subprocess may inherit additional environment variable
settings beyond those in the process builder's {@link #environment()}.
<p>If there is a security manager, its
{@link SecurityManager#checkExec checkExec}
method is called with the first component of this object's
{@code command} array as its argument. This may result in
a {@link SecurityException} being thrown.
<p>Starting an operating system process is highly system-dependent.
Among the many things that can go wrong are:
<ul>
<li>The operating system program file was not found.
<li>Access to the program file was denied.
<li>The working directory does not exist.
</ul>
<p>In such cases an exception will be thrown. The exact nature
of the exception is system-dependent, but it will always be a
subclass of {@link IOException}.
<p>Subsequent modifications to this process builder will not
affect the returned {@link Process}.
@return a new {@link Process} object for managing the subprocess
*
* @throws NullPointerException
* if an element of the command list is null
*
* @throws IndexOutOfBoundsException
* if the command is an empty list (has size {@code 0})
*
* @throws SecurityException
* if a security manager exists and
* <ul>
*
* <li>its
* {@link SecurityManager#checkExec checkExec}
* method doesn't allow creation of the subprocess, or
*
* <li>the standard input to the subprocess was
* {@linkplain #redirectInput redirected from a file}
* and the security manager's
* {@link SecurityManager#checkRead checkRead} method
* denies read access to the file, or
*
* <li>the standard output or standard error of the
* subprocess was
* {@linkplain #redirectOutput redirected to a file}
* and the security manager's
* {@link SecurityManager#checkWrite checkWrite} method
* denies write access to the file
*
* </ul>
*
* @throws IOException if an I/O error occurs
*
* @see Runtime#exec(String[], String[], java.io.File)
*/
public Process start() throws IOException {
// Must convert to array first -- a malicious user-supplied
// list might try to circumvent the security check.
String[] cmdarray = command.toArray(new String[command.size()]);
cmdarray = cmdarray.clone();
for (String arg : cmdarray)
if (arg == null)
throw new NullPointerException();
// Throws IndexOutOfBoundsException if command is empty
String prog = cmdarray[0];
SecurityManager security = System.getSecurityManager();
if (security != null)
security.checkExec(prog);
String dir = directory == null ? null : directory.toString();
for (int i = 1; i < cmdarray.length; i++) {
if (cmdarray[i].indexOf('\u0000') >= 0) {
throw new IOException("invalid null character in command");
}
}
try {
return ProcessImpl.start(cmdarray,
environment,
dir,
redirects,
redirectErrorStream);
} catch (IOException | IllegalArgumentException e) {
String exceptionInfo = ": " + e.getMessage();
Throwable cause = e;
if ((e instanceof IOException) && security != null) {
// Can not disclose the fail reason for read-protected files.
try {
security.checkRead(prog);
} catch (SecurityException se) {
exceptionInfo = "";
cause = se;
}
}
// It's much easier for us to create a high-quality error
// message than the low-level C code which found the problem.
throw new IOException(
"Cannot run program \"" + prog + "\""
+ (dir == null ? "" : " (in directory \"" + dir + "\")")
+ exceptionInfo,
cause);
}
}