Java StreamGobbler输出短或过程非常快

Java StreamGobbler输出短或过程非常快,java,io,Java,Io,我使用StreamGobbler读取外部程序的输出。以前,我习惯于读取和解析ffmpeg的stderr输出的大字符串(20-40个字符串)。现在我只想从identify(ImageMagick)的stdout中读取和解析一个字符串(一个字符串是程序的所有输出,这个程序很快结束)。有时它可以工作,但有时我会出现错误“流关闭”。我认为streamGobler没有时间处理stream(流程在streamGobler完成一些工作之前结束) 下面您可以看到类ExecThread及其用法示例 对不起,我的英

我使用StreamGobbler读取外部程序的输出。以前,我习惯于读取和解析ffmpeg的stderr输出的大字符串(20-40个字符串)。现在我只想从identify(ImageMagick)的stdout中读取和解析一个字符串(一个字符串是程序的所有输出,这个程序很快结束)。有时它可以工作,但有时我会出现错误“流关闭”。我认为streamGobler没有时间处理stream(流程在streamGobler完成一些工作之前结束)

下面您可以看到类ExecThread及其用法示例

对不起,我的英语。。。


我建议进行两项修改:

  • 使用,而不是写线程
  • 关闭输入、输出和错误流并销毁该进程。如果不这样做,您将有文件句柄泄漏

  • 这不是一个好决定,但它是有效的。之前是
    String命令=identifyExe.getAbsolutePath()+“\”+文件.getAbsolutePath()+“\”
    现在它是
    String command=“sleep 1;”+identifyExe.getAbsolutePath()+“\”+文件.getAbsolutePath()+“\”

    睡眠是非常有用的功能:-)


    但,若你们知道更好的决定,请告诉…

    我使用进程,但它运行在其他线程中(不在主线程中)。我在函数waitfore中破坏了它,你不关闭你的流。除非你确信毁灭会帮你解决,否则悲伤是肯定的。谢谢!我添加了关闭StreamGobbler和BufferedReaders。但是没有睡眠(见我的问题答案)并不能解决问题。你不应该需要睡眠。我知道使用睡眠是不好的,但没有睡眠是不行的。一点建议:在某些情况下,你可以回答你自己的问题,但你不应该模拟对话。我不会像你那样写的。
        String command =  ffmpegExe.getAbsolutePath()+ " -i \""+ fileName +"\"";
        ExecThread thread = new ExecThread(command);
        thread.setPriority(ExecThread.MIN_PRIORITY);
        thread.start();
        thread.waitFor(DEFAULT_WAIT);
    
        //reading ffmpeg stderr
        BufferedReader ffmpegErr = thread.getErrBufferedReader();
        String line;
    
        try
        {
            while((line = ffmpegErr.readLine()) !=null)
    //some code
    
    
    
    private static class ExecThread extends  Thread
    {
        public ExecThread(String command)
        {
            this.command = command;
        }
        @Override
        public void run()
        {
    
            try
            {
                ExecCommand(command);
                exitVal = process.waitFor();
            }
            catch (Exception e )
            {
                logger.error("Error while executing command: " + command + e.getMessage(),e);
                System.err.println("Error");
                System.exit(1);
            }
        }
        public void waitFor(long millis)
        {
            try
            {
                this.join(millis);
                process.destroy();
            } catch (Exception e)
            {
                logger.error("Error while interupting command: " + command + e.getMessage(), e);
            }
    
        }
    
    
        private  void ExecCommand(String command) throws IOException
        {
            //run command
            Runtime rt = Runtime.getRuntime();
            process = rt.exec(new String[]{shellName,shellOption, command}, null, null);
    
            //get stderr buffered reader
            StreamGobbler errGobbler = new StreamGobbler(process.getErrorStream());
            StreamGobbler outGobbler = new StreamGobbler(process.getInputStream());
    
            ErrBufferedReader = new BufferedReader(new InputStreamReader(errGobbler));
            OutBufferedReader = new BufferedReader(new InputStreamReader(outGobbler));
    
        }
        private BufferedReader ErrBufferedReader;
    
        public BufferedReader getOutBufferedReader()
        {
            return OutBufferedReader;
        }
    
        private BufferedReader OutBufferedReader;
        private Process process;
        private String command;
        private int exitVal=-1;
    
        public BufferedReader getErrBufferedReader()
        {
            return ErrBufferedReader;
        }
    
        public Process getProcess()
        {
            return process;
        }
    
        public String getCommand()
        {
            return command;
        }
    
        public int getExitVal()
        {
            return exitVal;
        }
    }