流吞噬者输出短或非常快的过程



>我使用StreamGobbler从外部程序读取输出。在我曾经从 ffmpeg 的 stderr 读取和解析 big(20-40 个字符串)输出之前。现在我只想从 stdout 中读取和解析一个字符串(一个字符串是程序的所有输出,这个程序结束得很快)的 idunify(ImageMagick)。有时它可以工作,但有时我有错误"流关闭"。我认为 StreamGobbler 没有时间使用 stream(进程在 streamGobler 做一些工作之前结束)。

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

对不起我的英语...

    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;
    }
}

我建议进行两项更改:

  1. 使用 Java 进程而不是编写线程。
  2. 关闭输入、输出和错误流并销毁进程。 如果不这样做,您将面临文件句柄泄漏。

这不是一个好决定,但它有效。在它被String command = identifyExe.getAbsolutePath() + " "" + file.getAbsolutePath() + """;之前现在它String command = "sleep 1 ; " + identifyExe.getAbsolutePath() + " "" + file.getAbsolutePath() + """;

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

但是,如果您知道更好的决定,请告诉...

相关内容

最新更新