ProcessBuilder无法返回JSon String

时间:2017-01-24 11:04:14

标签: java json child-process

我正在使用ProcessBuilder来运行命令。 命令输出是jSON格式,我想返回String,然后用我的模型映射它。

问题是我在尝试从进程中读取流时没有得到任何结果。 我使用的命令也有一个非jSON输出。如果我使用此命令版本,我会得到结果,所以只有当我想读取jSON时才会出现问题..

public String getPlate(String image) throws IOException, InterruptedException{
        ProcessBuilder pb = new ProcessBuilder("alpr", "-c eu", "-j on", "-n 1", image);
        Process p = pb.start();
        p.waitFor();
        BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
        StringBuilder builder = new StringBuilder();
        String line;
        while ( (line = reader.readLine()) != null) {
               builder.append(line);
               builder.append(System.getProperty("line.separator"));
            }
            String result = builder.toString();
            return result;
    }

如果我使用非jSON版本

,使用此命令时,不会给出结果
ProcessBuilder pb = new ProcessBuilder("alpr", "-c eu", "-n 1", image);

我有结果..

1 个答案:

答案 0 :(得分:4)

您的过程几乎肯定是阻塞的,因为它的输出没有被读取。你没有开始阅读它的输出直到它完成,并且它不能完成直到它的输出被读取,因为你的子进程产生足够的输出来填充父进程和子进程之间的管道缓冲区。由于在孩子运行时没有任何东西正在读取管道,因此它会阻止尝试写入。

您的非JSON输出可能更小,因此它不会填充流程输出流中的管道缓冲区,从而允许该过程完成,然后您的父Java进程可以读取管道缓冲区中的数据。

您需要更改您正在执行的操作的顺序:

public String getPlate(String image) throws IOException, InterruptedException{
        ProcessBuilder pb =
            new ProcessBuilder("alpr", "-c eu", "-j on", "-n 1", image);
        Process p = pb.start();

        BufferedReader reader =
            new BufferedReader(new InputStreamReader(p.getInputStream()));
        StringBuilder builder = new StringBuilder();
        String line;
        while ( (line = reader.readLine()) != null) {
               builder.append(line);
               builder.append(System.getProperty("line.separator"));
        }

        // wait for the child process *after*
        // reading all its output
        p.waitFor();

        String result = builder.toString();
        return result;
}

这是一个快速解决方案 - 它实际上不是很强大。如果您的子进程也生成了重要的错误输出,那么也会阻塞。

您可以根据需要使用redirectError(), redirectInput(), and redirectOutput()方法来阻止此类阻止。