Writing to InputStream of a Java Process
Asked Answered
V

2

29

I have a code that starts a java process (i.e.: executing a compiled java code) via

ProcessBuilder builder = new ProcessBuilder("java", "Sample", "arg1", "arg2");
builder.redirectErrorStream(true);
Process process = builder.start();

Through this, I can basically process the output and errors

OutputStream stdin = process.getOutputStream(); // <- Eh?
InputStream stdout = process.getInputStream();

BufferedReader reader = new BufferedReader(new InputStreamReader(stdout));
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(stdin));

// reader.readLine() blah blah

Now, how can I send input to the stdin? That is, if the code executed by the process has a line that waits for an input as in:

Scanner scan = new Scanner(System.in);
String val = scan.nextLine();
System.out.println(val);

I tried this:

writer.write("I'm from the stdin!.");
writer.flush();

Though nothing happened. The console still waited for an input.

Any thoughts?

EDIT: The question was answered, as accepted below. I'm editing to show the faulty code (which I failed to include btw. Lol).

Before the writer.write() part, I had a

String line;
line = reader.readLine();
while (line != null) {
    System.out.println(line);
    line = reader.readLine();
}
Vladimir answered 19/9, 2013 at 19:41 Comment(5)
I am not sure but try sending a \n character to signal EOL.Suburbanize
I tried it with ...from the stdin!\n");. Nothing changed though. :|Vladimir
Look up ASCII table and send CRLF codes in a sepearate flush, sorry I am on my mobile can't look that up for you.Suburbanize
Here's what I did writer.write("I'm from the stdin."); writer.write("\r\n"); writer.flush();Vladimir
Try flushing before writing the CRLF.Suburbanize
H
62

The Process OutputStream (our point of view) is the STDIN from the process point of view

OutputStream stdin = process.getOutputStream(); // write to this

So what you have should be correct.

My driver (apply your own best practices with try-with-resources statements)

public class ProcessWriter {
    public static void main(String[] args) throws Exception {
        ProcessBuilder builder = new ProcessBuilder("java", "Test");
        builder.directory(new File("C:\\Users\\sotirios.delimanolis\\Downloads"));
        Process process = builder.start();

        OutputStream stdin = process.getOutputStream(); // <- Eh?
        InputStream stdout = process.getInputStream();

        BufferedReader reader = new BufferedReader(new InputStreamReader(stdout));
        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(stdin));

        writer.write("Sup buddy");
        writer.flush();
        writer.close();

        Scanner scanner = new Scanner(stdout);
        while (scanner.hasNextLine()) {
            System.out.println(scanner.nextLine());
        }
    }
}

My application

public class Test {

    public static void main(String[] args) throws Exception {
        Scanner console = new Scanner(System.in);
        System.out.println("heello World");
        while(console.hasNextLine()) {
            System.out.println(console.nextLine());
        }
    }
}

Running the driver prints

heello World
Sup buddy

For some reason I need the close(). The flush() alone won't do it.

Edit It also works if instead of the close() you provide a \n.

So with

writer.write("Sup buddy");
writer.write("\n");
writer.write("this is more\n");
writer.flush();    

the driver prints

heello World
Sup buddy
this is more
Hooker answered 19/9, 2013 at 19:44 Comment(0)
I
6

This is an example which maybe can helps someone

import java.io.IOException;
import java.io.File;
import java.io.OutputStream;
import java.io.InputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) throws IOException {
        String[] commands = {"C:/windows/system32/cmd.exe"};
        ProcessBuilder builder = new ProcessBuilder(commands);
        builder.directory(new File("C:/windows/system32"));
        Process process = builder.start();

        OutputStream stdin = process.getOutputStream();
        InputStream stdout = process.getInputStream();
        InputStream stderr = process.getErrorStream();

        BufferedReader reader = new BufferedReader(new InputStreamReader(stdout));
        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(stdin));
        BufferedReader error = new BufferedReader(new InputStreamReader(stderr));

        new Thread(() -> {
            String read;
            try {
                while ((read = reader.readLine()) != null) {
                    System.out.println(read);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }).start();

        new Thread(() -> {
            String read;
            try {
                while ((read = error.readLine()) != null) {
                    System.out.println(read);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }).start();

        new Thread(() -> {
            while (true) {
                try {
                    Scanner scanner = new Scanner(System.in);
                    writer.write(scanner.nextLine());
                    writer.newLine();
                    writer.flush();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }
}
Ilion answered 29/11, 2021 at 14:7 Comment(2)
Thank you for this code snippet, which might provide some limited, immediate help. A proper explanation would greatly improve its long-term value by showing why this is a good solution to the problem and would make it more useful to future readers with other, similar questions. Please edit your answer to add some explanation, including the assumptions you’ve made.Atypical
Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.Glossary

© 2022 - 2024 — McMap. All rights reserved.