-1
    Process p = Runtime.getRuntime().exec("myexe.exe");

    BufferedReader br = null;
    try{
       br = new BufferedReader(new InputStreamReader(p.getInputStream(),       "GB2312"));
       String value = null;
       while ((line = br.readLine()) != null) {
           System.out.println(line);
       }
    }finally{
       IOUtils.close(br);
    }

Then, the output likes below, not the string I want:

Child: Can't read length for data, error code 109

Yanhui Zhou
  • 872
  • 6
  • 20

1 Answers1

2

It seems that the problem appears, because of the output of the exe which is too long. Can ProcessBuilder solve it ?

As a general rule of thumb, you should always read the output of Process before you call waitFor (or use a background Thread to read it while you waitFor)

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("myexe.exe");
        pb.redirectErrorStream(true);
        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);
            e.printStackTrace();
        }
    }

    public static class InputConsumer extends Thread {

        private InputStream is;

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

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

    }

}

In the past, I've either provided an Observer Pattern to the InputConsumer, through which some other party can be notified as new input comes in or otherwised cached the output so I can process it after the process has completed, based on your needs

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • Thanks, you are right about`waitfor`. But the problem of too long output data is not solved. – Yanhui Zhou Mar 01 '16 at 10:19
  • Is the exe file based python? Without any ideas of what that exe is does or how it works, that's going to be the best we can do – MadProgrammer Mar 01 '16 at 10:22
  • You could also try using [`ProcessBuilder#inheritIO`](https://docs.oracle.com/javase/8/docs/api/java/lang/ProcessBuilder.html#inheritIO--) before you start the process – MadProgrammer Mar 01 '16 at 10:25
  • Thanks again. The exe is based on c++ written by myself. And it runs ok independently. After searching from google, I found my problem was because of [ERROR_BROKEN_PIPE](https://msdn.microsoft.com/en-us/library/windows/desktop/ms681382(v=vs.85).aspx), which is related to the limitation of Windows's default setting. So, I will change my implementation of my application. – Yanhui Zhou Mar 01 '16 at 10:33