同步操作将从 Stefan/Java8Source 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
/** Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.*********************/package java.lang;import java.io.File;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.util.Arrays;import java.util.ArrayList;import java.util.List;import java.util.Map;/*** This class is used to create operating system processes.** <p>Each {@code ProcessBuilder} instance manages a collection* of process attributes. The {@link #start()} method creates a new* {@link Process} instance with those attributes. The {@link* #start()} method can be invoked repeatedly from the same instance* to create new subprocesses with identical or related attributes.** <p>Each process builder manages these process attributes:** <ul>** <li>a <i>command</i>, a list of strings which signifies the* external program file to be invoked and its arguments, if any.* Which string lists represent a valid operating system command is* system-dependent. For example, it is common for each conceptual* argument to be an element in this list, but there are operating* systems where programs are expected to tokenize command line* strings themselves - on such a system a Java implementation might* require commands to contain exactly two elements.** <li>an <i>environment</i>, which is a system-dependent mapping from* <i>variables</i> to <i>values</i>. The initial value is a copy of* the environment of the current process (see {@link System#getenv()}).** <li>a <i>working directory</i>. The default value is the current* working directory of the current process, usually the directory* named by the system property {@code user.dir}.** <li><a name="redirect-input">a source of <i>standard input</i></a>.* By default, the subprocess reads input from a pipe. Java code* can access this pipe via the output stream returned by* {@link Process#getOutputStream()}. However, standard input may* be redirected to another source using* {@link #redirectInput(Redirect) redirectInput}.* In this case, {@link Process#getOutputStream()} will return a* <i>null output stream</i>, for which:** <ul>* <li>the {@link OutputStream#write(int) write} methods always* throw {@code IOException}* <li>the {@link OutputStream#close() close} method does nothing* </ul>** <li><a name="redirect-output">a destination for <i>standard output</i>* and <i>standard error</i></a>. By default, the subprocess writes standard* output and standard error to pipes. Java code can access these pipes* via the input streams returned by {@link Process#getInputStream()} and* {@link Process#getErrorStream()}. However, standard output and* standard error may be redirected to other destinations using* {@link #redirectOutput(Redirect) redirectOutput} and* {@link #redirectError(Redirect) redirectError}.* In this case, {@link Process#getInputStream()} and/or* {@link Process#getErrorStream()} will return a <i>null input* stream</i>, for which:** <ul>* <li>the {@link InputStream#read() read} methods always return* {@code -1}* <li>the {@link InputStream#available() available} method always returns* {@code 0}* <li>the {@link InputStream#close() close} method does nothing* </ul>** <li>a <i>redirectErrorStream</i> property. Initially, this property* is {@code false}, meaning that the standard output and error* output of a subprocess are sent to two separate streams, which can* be accessed using the {@link Process#getInputStream()} and {@link* Process#getErrorStream()} methods.** <p>If the value is set to {@code true}, then:** <ul>* <li>standard error is merged with the standard output and always sent* to the same destination (this makes it easier to correlate error* messages with the corresponding output)* <li>the common destination of standard error and standard output can be* redirected using* {@link #redirectOutput(Redirect) redirectOutput}* <li>any redirection set by the* {@link #redirectError(Redirect) redirectError}* method is ignored when creating a subprocess* <li>the stream returned from {@link Process#getErrorStream()} will* always be a <a href="#redirect-output">null input stream</a>* </ul>** </ul>** <p>Modifying a process builder's attributes will affect processes* subsequently started by that object's {@link #start()} method, but* will never affect previously started processes or the Java process* itself.** <p>Most error checking is performed by the {@link #start()} method.* It is possible to modify the state of an object so that {@link* #start()} will fail. For example, setting the command attribute to* an empty list will not throw an exception unless {@link #start()}* is invoked.** <p><strong>Note that this class is not synchronized.</strong>* If multiple threads access a {@code ProcessBuilder} instance* concurrently, and at least one of the threads modifies one of the* attributes structurally, it <i>must</i> be synchronized externally.** <p>Starting a new process which uses the default working directory* and environment is easy:** <pre> {@code* Process p = new ProcessBuilder("myCommand", "myArg").start();* }</pre>** <p>Here is an example that starts a process with a modified working* directory and environment, and redirects standard output and error* to be appended to a log file:** <pre> {@code* 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;* }</pre>** <p>To start a process with an explicit set of environment* variables, first call {@link java.util.Map#clear() Map.clear()}* before adding environment variables.** @author Martin Buchholz* @since 1.5*/public final class ProcessBuilder{private List<String> command;private File directory;private Map<String,String> environment;private boolean redirectErrorStream;private Redirect[] redirects;/*** Constructs a process builder with the specified operating* system program and arguments. This constructor does <i>not</i>* make a copy of the {@code command} list. Subsequent* updates to the list will be reflected in the state of the* process builder. It is not checked whether* {@code command} corresponds to a valid operating system* command.** @param command the list containing the program and its arguments* @throws NullPointerException if the argument is null*/public ProcessBuilder(List<String> command) {if (command == null)throw new NullPointerException();this.command = command;}/*** Constructs a process builder with the specified operating* system program and arguments. 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. It is not checked whether* {@code command} corresponds to a valid operating system* command.** @param command a string array containing the program and its arguments*/public ProcessBuilder(String... command) {this.command = new ArrayList<>(command.length);for (String arg : command)this.command.add(arg);}/*** Sets this process builder's operating system program and* arguments. This method does <i>not</i> make a copy of the* {@code command} list. Subsequent updates to the list will* be reflected in the state of the process builder. It is not* checked whether {@code command} corresponds to a valid* operating system command.** @param command the list containing the program and its arguments* @return this process builder** @throws NullPointerException if the argument is null*/public ProcessBuilder command(List<String> command) {if (command == null)throw new NullPointerException();this.command = command;return this;}/*** Sets this process builder's operating system program and* arguments. This is a convenience method that sets the command* to a string list containing the same strings as the* {@code command} array, in the same order. It is not* checked whether {@code command} corresponds to a valid* operating system command.** @param command a string array containing the program and its arguments* @return this process builder*/public ProcessBuilder command(String... command) {this.command = new ArrayList<>(command.length);for (String arg : command)this.command.add(arg);return this;}/*** Returns this process builder's operating system program and* arguments. The returned list is <i>not</i> a copy. Subsequent* updates to the list will be reflected in the state of this* process builder.** @return this process builder's program and its arguments*/public List<String> command() {return command;}/*** Returns a string map view of this process builder's environment.** Whenever a process builder is created, the environment is* initialized to a copy of the current process environment (see* {@link System#getenv()}). Subprocesses subsequently started by* this object's {@link #start()} method will use this map as* their environment.** <p>The returned object may be modified using ordinary {@link* java.util.Map Map} operations. These modifications will be* visible to subprocesses started via the {@link #start()}* method. Two {@code ProcessBuilder} instances always* contain independent process environments, so changes to the* returned map will never be reflected in any other* {@code ProcessBuilder} instance or the values returned by* {@link System#getenv System.getenv}.** <p>If the system does not support environment variables, an* empty map is returned.** <p>The returned map does not permit null keys or values.* Attempting to insert or query the presence of a null key or* value will throw a {@link NullPointerException}.* Attempting to query the presence of a key or value which is not* of type {@link String} will throw a {@link ClassCastException}.** <p>The behavior of the returned map is system-dependent. A* system may not allow modifications to environment variables or* may forbid certain variable names or values. For this reason,* attempts to modify the map may fail with* {@link UnsupportedOperationException} or* {@link IllegalArgumentException}* if the modification is not permitted by the operating system.** <p>Since the external format of environment variable names and* values is system-dependent, there may not be a one-to-one* mapping between them and Java's Unicode strings. Nevertheless,* the map is implemented in such a way that environment variables* which are not modified by Java code will have an unmodified* native representation in the subprocess.** <p>The returned map and its collection views may not obey the* general contract of the {@link Object#equals} and* {@link Object#hashCode} methods.** <p>The returned map is typically case-sensitive on all platforms.** <p>If a security manager exists, its* {@link SecurityManager#checkPermission checkPermission} method* is called with a* {@link RuntimePermission}{@code ("getenv.*")} permission.* This may result in a {@link SecurityException} being thrown.** <p>When passing information to a Java subprocess,* <a href=System.html#EnvironmentVSSystemProperties>system properties</a>* are generally preferred over environment variables.** @return this process builder's environment** @throws SecurityException* if a security manager exists and its* {@link SecurityManager#checkPermission checkPermission}* method doesn't allow access to the process environment** @see Runtime#exec(String[],String[],java.io.File)* @see System#getenv()*/public Map<String,String> environment() {SecurityManager security = System.getSecurityManager();if (security != null)security.checkPermission(new RuntimePermission("getenv.*"));if (environment == null)environment = ProcessEnvironment.environment();assert environment != null;return environment;}// Only for use by Runtime.exec(...envp...)ProcessBuilder environment(String[] envp) {assert environment == null;if (envp != null) {environment = ProcessEnvironment.emptyEnvironment(envp.length);assert environment != null;for (String envstring : envp) {// Before 1.5, we blindly passed invalid envstrings// to the child process.// We would like to throw an exception, but do not,// for compatibility with old broken code.// Silently discard any trailing junk.if (envstring.indexOf((int) '\u0000') != -1)envstring = envstring.replaceFirst("\u0000.*", "");int eqlsign =envstring.indexOf('=', ProcessEnvironment.MIN_NAME_LENGTH);// Silently ignore envstrings lacking the required `='.if (eqlsign != -1)environment.put(envstring.substring(0,eqlsign),envstring.substring(eqlsign+1));}}return this;}/*** Returns this process builder's working directory.** Subprocesses subsequently started by this object's {@link* #start()} method will use this as their working directory.* The returned value may be {@code null} -- this means to use* the working directory of the current Java process, usually the* directory named by the system property {@code user.dir},* as the working directory of the child process.** @return this process builder's working directory*/public File directory() {return directory;}/*** Sets this process builder's working directory.** Subprocesses subsequently started by this object's {@link* #start()} method will use this as their working directory.* The argument may be {@code null} -- this means to use the* working directory of the current Java process, usually the* directory named by the system property {@code user.dir},* as the working directory of the child process.** @param directory the new working directory* @return this process builder*/public ProcessBuilder directory(File directory) {this.directory = directory;return this;}// ---------------- I/O Redirection ----------------/*** Implements a <a href="#redirect-output">null input stream</a>.*/static class NullInputStream extends InputStream {static final NullInputStream INSTANCE = new NullInputStream();private NullInputStream() {}public int read() { return -1; }public int available() { return 0; }}/*** Implements a <a href="#redirect-input">null output stream</a>.*/static class NullOutputStream extends OutputStream {static final NullOutputStream INSTANCE = new NullOutputStream();private NullOutputStream() {}public void write(int b) throws IOException {throw new IOException("Stream closed");}}/*** Represents a source of subprocess input or a destination of* subprocess output.** Each {@code Redirect} instance is one of the following:** <ul>* <li>the special value {@link #PIPE Redirect.PIPE}* <li>the special value {@link #INHERIT Redirect.INHERIT}* <li>a redirection to read from a file, created by an invocation of* {@link Redirect#from Redirect.from(File)}* <li>a redirection to write to a file, created by an invocation of* {@link Redirect#to Redirect.to(File)}* <li>a redirection to append to a file, created by an invocation of* {@link Redirect#appendTo Redirect.appendTo(File)}* </ul>** <p>Each of the above categories has an associated unique* {@link Type Type}.** @since 1.7*/public static abstract class Redirect {/*** The type of a {@link Redirect}.*/public enum Type {/*** The type of {@link Redirect#PIPE Redirect.PIPE}.*/PIPE,/*** The type of {@link Redirect#INHERIT Redirect.INHERIT}.*/INHERIT,/*** The type of redirects returned from* {@link Redirect#from Redirect.from(File)}.*/READ,/*** The type of redirects returned from* {@link Redirect#to Redirect.to(File)}.*/WRITE,/*** The type of redirects returned from* {@link Redirect#appendTo Redirect.appendTo(File)}.*/APPEND};/*** Returns the type of this {@code Redirect}.* @return the type of this {@code Redirect}*/public abstract Type type();/*** Indicates that subprocess I/O will be connected to the* current Java process over a pipe.** This is the default handling of subprocess standard I/O.** <p>It will always be true that* <pre> {@code* Redirect.PIPE.file() == null &&* Redirect.PIPE.type() == Redirect.Type.PIPE* }</pre>*/public static final Redirect PIPE = new Redirect() {public Type type() { return Type.PIPE; }public String toString() { return type().toString(); }};/*** Indicates that subprocess I/O source or destination will be the* same as those of the current process. This is the normal* behavior of most operating system command interpreters (shells).** <p>It will always be true that* <pre> {@code* Redirect.INHERIT.file() == null &&* Redirect.INHERIT.type() == Redirect.Type.INHERIT* }</pre>*/public static final Redirect INHERIT = new Redirect() {public Type type() { return Type.INHERIT; }public String toString() { return type().toString(); }};/*** Returns the {@link File} source or destination associated* with this redirect, or {@code null} if there is no such file.** @return the file associated with this redirect,* or {@code null} if there is no such file*/public File file() { return null; }/*** When redirected to a destination file, indicates if the output* is to be written to the end of the file.*/boolean append() {throw new UnsupportedOperationException();}/*** Returns a redirect to read from the specified file.** <p>It will always be true that* <pre> {@code* Redirect.from(file).file() == file &&* Redirect.from(file).type() == Redirect.Type.READ* }</pre>** @param file The {@code File} for the {@code Redirect}.* @throws NullPointerException if the specified file is null* @return a redirect to read from the specified file*/public static Redirect from(final File file) {if (file == null)throw new NullPointerException();return new Redirect() {public Type type() { return Type.READ; }public File file() { return file; }public String toString() {return "redirect to read from file \"" + file + "\"";}};}/*** Returns a redirect to write to the specified file.* If the specified file exists when the subprocess is started,* its previous contents will be discarded.** <p>It will always be true that* <pre> {@code* Redirect.to(file).file() == file &&* Redirect.to(file).type() == Redirect.Type.WRITE* }</pre>** @param file The {@code File} for the {@code Redirect}.* @throws NullPointerException if the specified file is null* @return a redirect to write to the specified file*/public static Redirect to(final File file) {if (file == null)throw new NullPointerException();return new Redirect() {public Type type() { return Type.WRITE; }public File file() { return file; }public String toString() {return "redirect to write to file \"" + file + "\"";}boolean append() { return false; }};}/*** Returns a redirect to append to the specified file.* Each write operation first advances the position to the* end of the file and then writes the requested data.* Whether the advancement of the position and the writing* of the data are done in a single atomic operation is* system-dependent and therefore unspecified.** <p>It will always be true that* <pre> {@code* Redirect.appendTo(file).file() == file &&* Redirect.appendTo(file).type() == Redirect.Type.APPEND* }</pre>** @param file The {@code File} for the {@code Redirect}.* @throws NullPointerException if the specified file is null* @return a redirect to append to the specified file*/public static Redirect appendTo(final File file) {if (file == null)throw new NullPointerException();return new Redirect() {public Type type() { return Type.APPEND; }public File file() { return file; }public String toString() {return "redirect to append to file \"" + file + "\"";}boolean append() { return true; }};}/*** Compares the specified object with this {@code Redirect} for* equality. Returns {@code true} if and only if the two* objects are identical or both objects are {@code Redirect}* instances of the same type associated with non-null equal* {@code File} instances.*/public boolean equals(Object obj) {if (obj == this)return true;if (! (obj instanceof Redirect))return false;Redirect r = (Redirect) obj;if (r.type() != this.type())return false;assert this.file() != null;return this.file().equals(r.file());}/*** Returns a hash code value for this {@code Redirect}.* @return a hash code value for this {@code Redirect}*/public int hashCode() {File file = file();if (file == null)return super.hashCode();elsereturn file.hashCode();}/*** No public constructors. Clients must use predefined* static {@code Redirect} instances or factory methods.*/private Redirect() {}}private Redirect[] redirects() {if (redirects == null)redirects = new Redirect[] {Redirect.PIPE, Redirect.PIPE, Redirect.PIPE};return redirects;}/*** Sets this process builder's standard input source.** Subprocesses subsequently started by this object's {@link #start()}* method obtain their standard input from this source.** <p>If the source is {@link Redirect#PIPE Redirect.PIPE}* (the initial value), then the standard input of a* subprocess can be written to using the output stream* returned by {@link Process#getOutputStream()}.* If the source is set to any other value, then* {@link Process#getOutputStream()} will return a* <a href="#redirect-input">null output stream</a>.** @param source the new standard input source* @return this process builder* @throws IllegalArgumentException* if the redirect does not correspond to a valid source* of data, that is, has type* {@link Redirect.Type#WRITE WRITE} or* {@link Redirect.Type#APPEND APPEND}* @since 1.7*/public ProcessBuilder redirectInput(Redirect source) {if (source.type() == Redirect.Type.WRITE ||source.type() == Redirect.Type.APPEND)throw new IllegalArgumentException("Redirect invalid for reading: " + source);redirects()[0] = source;return this;}/*** Sets this process builder's standard output destination.** Subprocesses subsequently started by this object's {@link #start()}* method send their standard output to this destination.** <p>If the destination is {@link Redirect#PIPE Redirect.PIPE}* (the initial value), then the standard output of a subprocess* can be read using the input stream returned by {@link* Process#getInputStream()}.* If the destination is set to any other value, then* {@link Process#getInputStream()} will return a* <a href="#redirect-output">null input stream</a>.** @param destination the new standard output destination* @return this process builder* @throws IllegalArgumentException* if the redirect does not correspond to a valid* destination of data, that is, has type* {@link Redirect.Type#READ READ}* @since 1.7*/public ProcessBuilder redirectOutput(Redirect destination) {if (destination.type() == Redirect.Type.READ)throw new IllegalArgumentException("Redirect invalid for writing: " + destination);redirects()[1] = destination;return this;}/*** Sets this process builder's standard error destination.** Subprocesses subsequently started by this object's {@link #start()}* method send their standard error to this destination.** <p>If the destination is {@link Redirect#PIPE Redirect.PIPE}* (the initial value), then the error output of a subprocess* can be read using the input stream returned by {@link* Process#getErrorStream()}.* If the destination is set to any other value, then* {@link Process#getErrorStream()} will return a* <a href="#redirect-output">null input stream</a>.** <p>If the {@link #redirectErrorStream redirectErrorStream}* attribute has been set {@code true}, then the redirection set* by this method has no effect.** @param destination the new standard error destination* @return this process builder* @throws IllegalArgumentException* if the redirect does not correspond to a valid* destination of data, that is, has type* {@link Redirect.Type#READ READ}* @since 1.7*/public ProcessBuilder redirectError(Redirect destination) {if (destination.type() == Redirect.Type.READ)throw new IllegalArgumentException("Redirect invalid for writing: " + destination);redirects()[2] = destination;return this;}/*** Sets this process builder's standard input source to a file.** <p>This is a convenience method. An invocation of the form* {@code redirectInput(file)}* behaves in exactly the same way as the invocation* {@link #redirectInput(Redirect) redirectInput}* {@code (Redirect.from(file))}.** @param file the new standard input source* @return this process builder* @since 1.7*/public ProcessBuilder redirectInput(File file) {return redirectInput(Redirect.from(file));}/*** Sets this process builder's standard output destination to a file.** <p>This is a convenience method. An invocation of the form* {@code redirectOutput(file)}* behaves in exactly the same way as the invocation* {@link #redirectOutput(Redirect) redirectOutput}* {@code (Redirect.to(file))}.** @param file the new standard output destination* @return this process builder* @since 1.7*/public ProcessBuilder redirectOutput(File file) {return redirectOutput(Redirect.to(file));}/*** Sets this process builder's standard error destination to a file.** <p>This is a convenience method. An invocation of the form* {@code redirectError(file)}* behaves in exactly the same way as the invocation* {@link #redirectError(Redirect) redirectError}* {@code (Redirect.to(file))}.** @param file the new standard error destination* @return this process builder* @since 1.7*/public ProcessBuilder redirectError(File file) {return redirectError(Redirect.to(file));}/*** Returns this process builder's standard input source.** Subprocesses subsequently started by this object's {@link #start()}* method obtain their standard input from this source.* The initial value is {@link Redirect#PIPE Redirect.PIPE}.** @return this process builder's standard input source* @since 1.7*/public Redirect redirectInput() {return (redirects == null) ? Redirect.PIPE : redirects[0];}/*** Returns this process builder's standard output destination.** Subprocesses subsequently started by this object's {@link #start()}* method redirect their standard output to this destination.* The initial value is {@link Redirect#PIPE Redirect.PIPE}.** @return this process builder's standard output destination* @since 1.7*/public Redirect redirectOutput() {return (redirects == null) ? Redirect.PIPE : redirects[1];}/*** Returns this process builder's standard error destination.** Subprocesses subsequently started by this object's {@link #start()}* method redirect their standard error to this destination.* The initial value is {@link Redirect#PIPE Redirect.PIPE}.** @return this process builder's standard error destination* @since 1.7*/public Redirect redirectError() {return (redirects == null) ? Redirect.PIPE : redirects[2];}/*** Sets the source and destination for subprocess standard I/O* to be the same as those of the current Java process.** <p>This is a convenience method. An invocation of the form* <pre> {@code* pb.inheritIO()* }</pre>* behaves in exactly the same way as the invocation* <pre> {@code* pb.redirectInput(Redirect.INHERIT)* .redirectOutput(Redirect.INHERIT)* .redirectError(Redirect.INHERIT)* }</pre>** This gives behavior equivalent to most operating system* command interpreters, or the standard C library function* {@code system()}.** @return this process builder* @since 1.7*/public ProcessBuilder inheritIO() {Arrays.fill(redirects(), Redirect.INHERIT);return this;}/*** Tells whether this process builder merges standard error and* standard output.** <p>If this property is {@code true}, then any error output* generated by subprocesses subsequently started by this object's* {@link #start()} method will be merged with the standard* output, so that both can be read using the* {@link Process#getInputStream()} method. This makes it easier* to correlate error messages with the corresponding output.* The initial value is {@code false}.** @return this process builder's {@code redirectErrorStream} property*/public boolean redirectErrorStream() {return redirectErrorStream;}/*** Sets this process builder's {@code redirectErrorStream} property.** <p>If this property is {@code true}, then any error output* generated by subprocesses subsequently started by this object's* {@link #start()} method will be merged with the standard* output, so that both can be read using the* {@link Process#getInputStream()} method. This makes it easier* to correlate error messages with the corresponding output.* The initial value is {@code false}.** @param redirectErrorStream the new property value* @return this process builder*/public ProcessBuilder redirectErrorStream(boolean redirectErrorStream) {this.redirectErrorStream = redirectErrorStream;return this;}/*** Starts a new process using the attributes of this process builder.** <p>The new process will* invoke the command and arguments given by {@link #command()},* in a working directory as given by {@link #directory()},* with a process environment as given by {@link #environment()}.** <p>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.** <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 emptyString 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);}}}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。