2017-01-24 5 views
3

Ich verwende ProcessBuilder, um einen Befehl auszuführen. Die Befehlsausgabe ist im jSON-Format, und ich möchte die Zeichenfolge zurückgeben und sie dann mit meinen Modellen abbilden.ProcessBuilder kann keine JSon-Zeichenfolge zurückgeben

Das Problem ist, ich bekomme kein Ergebnis, wenn Sie versuchen, den Stream aus dem Prozess zu lesen. Der Befehl, den ich verwende, hat auch einen nicht-jSON-Ausgang. Wenn ich diesen Befehl Version verwenden, ich das Ergebnis zu erhalten, so dass nur das Problem tritt auf, wenn ich JSon lesen will ..

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; 
    } 

Mit diesem Befehl wird kein Ergebnis gegeben, wenn ich die nicht-JSon Version verwenden

ProcessBuilder pb = new ProcessBuilder("alpr", "-c eu", "-n 1", image); 

ich habe das Ergebnis ..

Antwort

4

Ihr Prozess mit ziemlicher Sicherheit blockiert, weil sein Ausgang nicht gelesen wird. Die Ausgabe wird erst gelesen, wenn sie fertig ist, und sie kann erst beendet werden, wenn ihre Ausgabe gelesen wird, da der untergeordnete Prozess genügend Ausgabe generiert, um die Pipe-Puffer zwischen dem übergeordneten und dem untergeordneten Prozess zu füllen. Da nichts die Pipe liest, während das Kind läuft, blockiert es den Schreibversuch.

Ihre Nicht-JSON-Ausgabe ist wahrscheinlich kleiner, füllt also die Pipe-Puffer im Prozess-Ausgabestream nicht auf, sodass der Prozess abgeschlossen werden kann und der übergeordnete Java-Prozess die Daten in den Pipe-Puffern lesen kann.

Sie müssen die Reihenfolge ändern, was Sie tun:

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; 
} 

Das ist eine schnelle Lösung ist - es eigentlich nicht sehr robust ist. Wenn Ihr Kindprozess auch eine signifikante Fehlerausgabe generiert, kann dies ebenfalls blockieren.

Sie können die Methoden redirectError(), redirectInput(), and redirectOutput() verwenden, um diese Blockierung zu verhindern.

Verwandte Themen