3

我需要在启动后提取进程的输入流。今天我可以获得初始信息,但是在我关闭应用程序之前该方法不会返回(在这种情况下,应用程序由进程启动:gedit 和 firefox)。我的意思是,我知道它会在我关闭进程后返回,但我想有一个解决方法来在进程关闭之前得到它。请参阅下面的代码。

public class ProcessInvokerExtractingProcessInformation {

    public static void main(String args[]) {



        try {
            Process pOpenApp = new ProcessBuilder(new String[] { "gedit",
                    "/home/thais/Documents/gedit_doc1" }).start();

            printInformation("pOpenApp", pOpenApp);

            // * just for testing error message and input stream
            Process openFirefox = new ProcessBuilder(new String[] { "firefox" })
                    .start();
            printInformation("lsInstruction", openFirefox);


            deleteProcess(pOpenApp);
            deleteProcess(openFirefox);

        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } 
    }




    // method for testing information we can see regarding the process
    public static void printInformation(String id, final Process process) {

        System.out.println(" Process " + id + ":");

                    //tried to run in a separated thread but didn't work as well
            Runnable r = new Runnable(){
            public void run(){
                System.out.print("\n        Process error message -> ");
            printScannedStream(process.getErrorStream());
            System.out.println("\n        Process input message -> ");
            printScannedStream(process.getInputStream());
            }

            };

            Thread a = new Thread(r);
            a.start();



            /* other approaches to print the streams, tried before
                StringWriter writer = new StringWriter();

            try {
              PrintWriter pWriter = new PrintWriter(new
              BufferedOutputStream(process.getOutputStream()));
              pWriter.write("Hi"); pWriter.flush(); System.out.println(
              " Process output stream is for writing so there is no information "
              );
             *//*
            InputStreamReader isr = new InputStreamReader(
                    process.getErrorStream());
            BufferedReader br = new BufferedReader(isr);
            System.out.print("\n        Process error message -> ");
            while (br.readLine() != null) {
                System.out.print(br.readLine());
            }
            System.out.println("\n        Process input message -> ");

            isr = new InputStreamReader(process.getInputStream());
            br = new BufferedReader(isr);
            while (br.readLine() != null) {
                System.out.print(br.readLine());
            }

            br.close();
            isr.close();*/
            /*
             * IOUtils.copy(process.getErrorStream(), writer, null);
             * System.out.println("        Process error message -> " +
             * writer.toString());
             * 
             * IOUtils.copy(process.getInputStream(), writer, null);
             * System.out.println("        Process input stream message -> " +
             * writer.toString()+"\n");

        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
*/
    }

    /**
     * Method that close all streams and after destroy the process It's
     * important to close the streams to avoid file descriptions leaking
     * 
     * @param process
     */
    public static void deleteProcess(Process process) {
        try {
            process.getInputStream().close();
            process.getOutputStream().close();
            process.getErrorStream().close();
            process.destroy();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }



    public static void printScannedStream(java.io.InputStream is) {
        try {
            Scanner scanner = new Scanner(is);
            while(scanner.hasNext()) {
                System.out.print(scanner.next());

            }

        } catch (java.util.NoSuchElementException e) {
            e.printStackTrace();
        }


    }

}
4

1 回答 1

0

我有同样的问题,我用一个额外的线程解决了这个问题。

class InputHandler implements Runnable {

    InputStream input_;

    InputHandler(InputStream input) {
        input_ = input;
    }

    public void run() {
        try {
            int c;
            String line = "";
            while ((c = input_.read()) != -1) {
             if (((char) c == '\r') || ((char) c == '\n')) {
             if (!line.isEmpty()) flushString(line);
             line = "";
             } else
             line += (char) c;
            }
        } catch (Throwable t) {
            t.printStackTrace();
        }
    }

    private void flushString(String s) {
     // any code to process data from stream
     Logger.debug("library: " + getClass().getName() + ": compress: output: " + s);
    }

}




Process process = run.exec(ffmpegCmdString);
// read output
InputHandler stderrHandler = new InputHandler(process.getErrorStream());
new Thread(stderrHandler).start();
InputHandler stdoutHandler = new InputHandler(process.getInputStream());
new Thread(stdoutHandler).start();
process.waitFor();
于 2012-05-15T07:20:03.647 回答