Saltar al contenido

Diferencia entre ProcessBuilder y Runtime.exec()

Te doy la bienvenida a nuestra comunidad, en este lugar hallarás la solucíon que buscabas.

Solución:

Las diversas sobrecargas de Runtime.getRuntime().exec(...) tomar ya sea un array de cuerdas o una sola string. El soltero-string sobrecargas de exec() tokenizará el string en una array de argumentos, antes de pasar el string array sobre uno de los exec() sobrecargas que toma un string array. El ProcessBuilder los constructores, por otro lado, solo toman un varargs array de cuerdas o un List de cuerdas, donde cada string en el array o lista se supone que es un argumento individual. De cualquier manera, los argumentos obtenidos se unen en un string que se pasa al sistema operativo para ejecutar.

Entonces, por ejemplo, en Windows,

Runtime.getRuntime().exec("C:DoStuff.exe -arg1 -arg2");

ejecutará un DoStuff.exe programa con los dos argumentos dados. En este caso, la línea de comandos se tokeniza y se vuelve a armar. Sin embargo,

ProcessBuilder b = new ProcessBuilder("C:DoStuff.exe -arg1 -arg2");

fallará, a menos que haya un programa cuyo nombre sea DoStuff.exe -arg1 -arg2 en C:. Esto se debe a que no hay tokenización: se supone que el comando para ejecutar ya ha sido tokenizado. En su lugar, debe utilizar

ProcessBuilder b = new ProcessBuilder("C:DoStuff.exe", "-arg1", "-arg2");

o alternativamente

List params = java.util.Arrays.asList("C:DoStuff.exe", "-arg1", "-arg2");
ProcessBuilder b = new ProcessBuilder(params);

mira como Runtime.getRuntime().exec() pasa el comando String al ProcessBuilder. Utiliza un tokenizador y explota el comando en tokens individuales, luego invoca exec(String[] cmdarray, ......) que construye un ProcessBuilder.

Si construyes el ProcessBuilder con un array de cadenas en lugar de una sola, obtendrá el mismo resultado.

El ProcessBuilder constructor toma un String... vararg, por lo que pasar el comando completo como una sola cadena tiene el mismo efecto que invocar ese comando entre comillas en una terminal:

shell$ "command with args"

No hay diferencia entre ProcessBuilder.start() y Runtime.exec() porque la implementación de Runtime.exec() es:

public Process exec(String command) throws IOException 
    return exec(command, null, null);


public Process exec(String command, String[] envp, File dir)
    throws IOException 
    if (command.length() == 0)
        throw new IllegalArgumentException("Empty command");

    StringTokenizer st = new StringTokenizer(command);
    String[] cmdarray = new String[st.countTokens()];
    for (int i = 0; st.hasMoreTokens(); i++)
        cmdarray[i] = st.nextToken();
    return exec(cmdarray, envp, dir);


public Process exec(String[] cmdarray, String[] envp, File dir)
    throws IOException 
    return new ProcessBuilder(cmdarray)
        .environment(envp)
        .directory(dir)
        .start();

Así que código:

List list = new ArrayList<>();
new StringTokenizer(command)
.asIterator()
.forEachRemaining(str -> list.add((String) str));
new ProcessBuilder(String[])list.toArray())
            .environment(envp)
            .directory(dir)
            .start();

debe ser igual a:

Runtime.exec(command)

Gracias dave_thompson_085 para comentarios

Sección de Reseñas y Valoraciones

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *