2017-01-24 58 views
3

我使用ProcessBuilder來運行命令。 命令輸出爲jSON格式,我想返回字符串,然後將其與我的模型映射。ProcessBuilder無法返回JSon字符串

問題是我試圖從流程中讀取流時沒有得到任何結果。 我使用的命令也有一個非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); 

我有結果..

回答

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()方法來防止這種阻塞。