簡體   English   中英

“ffmpeg”:java.io.IOException:error = 24,打開的文件過多

[英]“ffmpeg”: java.io.IOException: error=24, Too many open files

我正在使用ffmpeg生成預覽,但是在我的程序執行過程中出現了這個錯誤:

“ffmpeg”:java.io.IOException:error = 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");
                                                }
 }

檢查ulimit -n輸出以查看允許從該shell生成的打開文件進程數。 歷史Unix系統限制為20個文件,但我的Ubuntu桌面默認為1024個打開的文件。

您可能需要在/etc/security/limits.conf文件中增加允許的打開文件數。 或者,您可能需要修改應用程序以更積極地關閉打開的文件。

另一種可能性是對可能打開的文件數量的系統范圍限制。 我不知道哪些現代系統仍然有這樣的限制,但首先要看的是sysctl -a輸出。 (好吧,也許是系統文檔之后的第二名 。)

請注意,每次調用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以選擇適合您需求的執行程序。

進程有一個方法: destroy()
嘗試在最后添加它。

每次使用Runtime ,它都會打開stdoutstderrstdin 完成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();
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM