-10

After getting feedback, I run the program but get no output in console

import java.io.File;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.*;
import java.io.InputStream;

class pbdemo {

    static public void main(String[] args) throws Exception {
        String s;
        ProcessBuilder pb = new ProcessBuilder("cmd.exe", "/f", "dir");
        pb.directory(new File("C:\\ljava"));
        try {
            Process pro = pb.start();
            pro.waitFor();
            BufferedReader br = new BufferedReader(new InputStreamReader(pro.getInputStream()));

            while ((s = br.readLine()) != null) {
                System.out.println("here we go" + s);
            }


        } catch (Exception e) {
            System.out.println("sorry" + e);
        }
    }
}

Program runs but gives no output.

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366

3 Answers3

1

The /F flag for CMD is for file completion. Its probably safe to assume that you want the /C flag to carry out the command. Without the /C flag, the cmd.exe will run interactively, looking for input, and your program will block indefinitely on waitFor. Replace:

new ProcessBuilder("cmd.exe", "/f", "dir");

with

new ProcessBuilder("cmd.exe", "/c", "dir");
Reimeus
  • 158,255
  • 15
  • 216
  • 276
1

You are waiting for the process to finish before attempting to read its output. But the chances are that it can finish writing all of that output until you've started reading it ... because the OS is not able to buffer it all. Net result, deadlock.

Change the code so that the pro.waitFor() call happens AFTER you have read all of the output.

(It is also possible that stuff may be written to the 'error' stream. But unless there is something seriously weird happening with the dir command, it is unlikely that it will generate enough error output to cause a deadlock. So it is probably OK to just ignore any (hypothetical) error output ... as you are currently doing.)

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
1

pro.waitFor(); is a blocking method. It will wait until the process has exited before returning. The problem with this is many programs will not exit until there standard out buffers have been read/cleared, meaning, in your case, it probably will never exit.

Try something like this instead...

import java.io.File;
import java.io.IOException;
import java.io.InputStream;

public class PBDemo {

    public static void main(String[] args) throws Exception {
        String s;
        ProcessBuilder pb = new ProcessBuilder("cmd.exe", "/c", "dir");
        pb.directory(new File("C:\\ljava"));
        pb.redirectError();
        try {
            Process pro = pb.start();
            InputConsumer ic = new InputConsumer(pro.getInputStream());
            System.out.println("...Waiting");
            int exitCode = pro.waitFor();

            ic.join();

            System.out.println("Process exited with " + exitCode);

        } catch (Exception e) {
            System.out.println("sorry" + e);
        }
    }

    public static class InputConsumer extends Thread {

        private InputStream is;

        public InputConsumer(InputStream is) {
            this.is = is;
            start();
        }

        @Override
        public void run() {
//            This is acutally a bad idea, not all process will write a new line ;)
//            BufferedReader br = new BufferedReader(new InputStreamReader(pro.getInputStream()));

            try {
                int in = -1;
                while ((in = is.read()) != -1) {
                    System.out.print((char) in);
                }
            } catch (IOException exp) {
                exp.printStackTrace();
            }
        }

    }

}
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366