java - 如何在进程完成之前提取 inputStream

标签 java process

我需要在启动进程后提取进程的输入流。 今天我可以获得初始信息,但是直到我关闭应用程序(在本例中,应用程序由进程启动: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();
        }


    }

}

最佳答案

我遇到了同样的问题,我用一个额外的线程解决了它。

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();

关于java - 如何在进程完成之前提取 inputStream,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10595816/

相关文章:

java - JPA 中的 PostgreSQL 函数 string_agg

java - FileLocator.toFileURL 在 IBM WebSphere 包中抛出 NPE

python - 与 Python 3 中的进程 ID 混淆

c# - 重复进程启动未按预期使用react

java - 通过 https ://获取 XML 数据

java - 实现堆栈时 ArrayList 与 ArrayDeque 的性能对比

java - 如何使用 java lambda 表达式将 List 传递给新对象的构造函数?

java - 从 Web 应用程序停止 Android 进程

windows - 关闭应用程序和从任务管理器结束进程有什么区别?

python - 使用 Python 跟踪进程状态