"ffmpeg": java.io.IOException: error = 24, слишком много открытых файлов - PullRequest
4 голосов
/ 04 августа 2010

Я работаю с ffmpeg для генерации предварительного просмотра, но я получаю эту ошибку в середине выполнения моей программы:

"ffmpeg": java.io.IOException: ошибка = 24, слишком много открытых файлов

Кто-нибудь знает, как решить или как избежать этого?
Я добавляю кусок кода, где я использую ffmpeg:

    for (int j = 0; j < temp.length; j++) {
                                                if(j==2){
                                                    String preview = temp2[i] + temp[j] +".jpg";
                                                    Process p = Runtime.getRuntime().exec("ffmpeg -i anotados/" +temp2[i] + " -r 1 -ss 00:00:"+temp[j]+" -t 1 -s 158x116 imagenes/" + preview);

                                                    TextOut.write(preview+"\n");
                                                }
 }

Ответы [ 4 ]

1 голос
/ 07 января 2012

У процесса есть метод: destroy().Попробуйте добавить его в конце.

1 голос
/ 04 августа 2010

Обратите внимание, что каждый вызов Runtime.exec порождает новый процесс, который выполняется параллельно.Вы уверены, что хотите порождать процессы настолько быстро, насколько это возможно?Вы, вероятно, хотите int exitValue = p.waitFor() дождаться завершения процесса.Если вам нужен параллелизм, я бы порекомендовал планировать задачи, используя java.util.concurrent.ThreadPoolExecutor.

Например, без особой проверки ошибок, что-то вроде этого:

final ExecutorService executor = Executors.newFixedThreadPool(2);

for (int j = 0; j < temp.length; j++) {
    if(j==2) {
        final String preview = temp2[i] + temp[j] +".jpg";
        final String ffmpegPreviewCommand = "ffmpeg -i anotados/" +temp2[i] + " -r 1 -ss 00:00:"+temp[j]+" -t 1 -s 158x116 imagenes/" + preview;

        executor.submit(new Callable() {
            @Override
            public Object call() throws Exception {
                final Process p = Runtime.getRuntime().exec(ffmpegPreviewCommand);
                final int exitValue = p.waitFor();
                //TODO Check ffmpeg's exit value.

                TextOut.write(preview+"\n");
            }
        });
}

// This waits for all scheduled tasks to be executed and terminates the executor.
executor.shutdown();

}

Посмотрите на java.util.concurrent.Executors, чтобы выбрать исполнителя, который соответствует вашим потребностям.

1 голос
/ 04 августа 2010

Проверьте вывод ulimit -n, чтобы увидеть, сколько разрешено иметь процессам открытых файлов, порожденным из этой оболочки. Исторические системы Unix имели ограничение в 20 файлов, но по умолчанию на моем рабочем столе Ubuntu установлено 1024 открытых файла.

Возможно, вам потребуется увеличить количество открытых файлов, которые вам разрешены в файле /etc/security/limits.conf. Или вам может потребоваться изменить приложение, чтобы оно более агрессивно закрывало открытые файлы.

Еще одна возможность - это общесистемное ограничение на количество файлов, которые могут быть открыты. Я не знаю, какие современные системы будут иметь такие ограничения, но первое, на что стоит обратить внимание, это вывод sysctl -a. (Ну, может быть второе место после системной документации.)

0 голосов
/ 04 августа 2010

Каждый раз, когда используется Runtime, открывается stdout, stderr и stdin. Убедитесь, что вы закрыли эти потоки, когда закончите с exec(). Что-то вроде

    if(j==2){
       String preview = temp2[i] + temp[j] +".jpg";
       Process p = Runtime.getRuntime().exec("ffmpeg -i anotados/" +temp2[i] + " -r 1 -ss      00:00:"+temp[j]+" -t 1 -s 158x116 imagenes/" + preview);
       TextOut.write(preview+"\n");

       //try this here 
       //add exception handling if necessary
       InputStream is = p.getInputStream();
       InputStream es = p.getErrorStream();
       OutputStream os = p.getOutputStream();
       is.close();
       es.close();
       os.close();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...