Writing in the child process
The simplest way to solve the problem is by recovering the return of the method Runtime#exec()
, who’s kind Process
and then using the method Process#getOutputStream
to be able to write directly on input of the process.
Example:
Process p = Runtime.getRuntime().exec("java MinhaClasse);
OutputStream stdin = process.getOutputStream();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(stdin));
writer.write("Valor 1\n");
writer.write("Valor 2\n");
writer.write("Valor 2\n");
writer.flush(); // pode chamar várias vezes, dependendo do volume
writer.close(); // opcional, somente quando acabar a entrada
The line break (\n
) after the values serve to emulate the key Enter the user presses when entering a value for the Scanner
.
Beware of buffers and deadlocks
Something very important is that whenever you write something for the child process you **should call the method flush()
of OutputStream
.
This is because the OutputStream
may have some buffer that may not reach the child process immediately, leaving it blocked indefinitely.
And such care is even more important if the parent process reads the child’s exit, in which case the two may be blocked indefinitely.
ProcessBuilder
Another tip is to use the ProcessBuilder
gives greater flexibility when building child process.
This can make a difference if there is a need to pass more parameters or something more complex.
Alternative #1 - using native resources
An alternative would still be to use the command line power of the operating system and do the pipe for input of the Java program from some text file. Example:
cat input.txt | java MinhaClasse
Alternative #2 - using a file as input
Another alternative to the competition is not to pass the data via programming in the main process. I believe this could influence the execution time of the program.
The idea would be to place the input file in a read-only directory on the disk and pass the path to this file as parameter to the program.
Then, just instruct the participants to create the Scanner
based on a constructor that receives a file.
Example:
public static void main(String[] args) {
Scanner input = new Scanner(new File(args[0));
...
}
Much simpler, without any implementation difficulty or risk to the execution.
Thank you very much, perfect.
– Danilo Souza