简体   繁体   English

Java Runtime exec()在一段时间后被卡住

[英]Java Runtime exec() get stuck after a while

I'm building a simple UI for ffmpeg launching ffmpeg.exe with parameters using exec(). 我正在为ffmpeg构建一个简单的UI,使用exec()使用参数启动ffmpeg.exe。 it works on Os X but on Windows 7-8 after few seconds the ffmpeg process suspends itself and resumes only when I kill the father process. 它可以在Os X上运行,但在Windows 7-8上,几秒钟后,ffmpeg进程将自行挂起并仅在我杀死父进程时才恢复。 (also ddlhost.exe is created) Ffmpeg.exe converts successfully the same video from cmd. (还会创建ddlhost.exe)Ffmpeg.exe成功转换了来自cmd的同一视频。

Searching on the internet I've found this answer but I have the same problem running a simple test program which is not using the Input and Error streams. 在Internet上搜索时,我已经找到了这个答案,但是在运行不使用Input和Error流的简单测试程序时,我也遇到了相同的问题。

Here is the test program code which has the same problem of the main one: 这是测试程序代码,它具有与主要代码相同的问题:

public class Main {

static String param_ffmpeg_1 = "./data/ffmpeg.exe";
static String param_ffmpeg_2 = "-i";

static String in = "./data/source.mov";
static String out = "./data/out.flv";

static Process p;

public static void main(String[] args) {

    /*File f = new File(out);

    if (f.exists()){
        f.delete();
    }*/


    Runtime rt = Runtime.getRuntime() ;
    //String cmd1 =  param_ffmpeg_1 + param_ffmpeg_2 +  in_path +  param_ffmpeg_3 + out_path ;
    System.out.println(in);
    System.out.println(out);
    String[] cmd1 = new String[] { param_ffmpeg_1, param_ffmpeg_2, in, "-ar", "44100", "-vb", "2500k", "-s", "882x496", "-f", "flv", out};

    try {
        p = rt.exec(cmd1);
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    int r = 123456;
    try {
        r = p.waitFor();
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    System.out.println(r);


}

} }

You should call getInputStream() and getErrorStream() on the Process returned by Runtime.exec and drain that all the time the process is running. 您应该在Runtime.exec返回的Process上调用getInputStream()getErrorStream() ,并在进程运行的所有时间消耗掉它。 If you do not then it will eventually fill up and block and stop the process from running. 如果不这样做,它将最终填满并阻塞并停止该进程的运行。

See Java Process with Input/Output Stream for examples. 有关示例,请参见带有输入/输出流的Java进程

From the accepted answer 接受的答案

ProcessBuilder builder = new ProcessBuilder("/bin/bash");
builder.redirectErrorStream(true);
Process process = builder.start();
InputStream itsOutput = process.getInputStream();
// Wrap the stream in a Reader ...
while ((line = reader.readLine ()) != null) {
    System.out.println ("Stdout: " + line);
}

Does ffmpg write anything to the stdout or stderr? ffmpg是否将任何内容写入stdout或stderr? If yes you have to consume that. 如果是,则必须消耗掉。 (In seperate threads as you need to consume the stderr and the stdout in parallel) see Process.getInputStream() and Process.getErrorStream() for the details. (在单独的线程中,您需要并行使用stderr和stdout Process.getErrorStream() ,有关详细信息,请参见Process.getInputStream()Process.getErrorStream() When the buffer is buffer is full your called programm is stopped and hangs. 当缓冲区已满时,被调用的程序将停止并挂起。

The fact that it works in OS/X but not Windows might be caused by different buffer sizes. 它可以在OS / X中运行但不能在Windows中运行的事实可能是由不同的缓冲区大小引起的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM