Wie Rohr InputStream zu ProcessBuilder
Bitte nach unten bewegen, um das 2. update. Ich nicht wollen, ändern Sie den vorherigen Kontext dieser Frage.
Ich bin mit wkhtmltoimage aus einer Java-app.
Den standard-Weg der Verwendung ist es - path-to-exe http://url.com/image.png
.
Entsprechend Ihrer docs, wenn wir schreiben eine -
anstelle eines input-URL, die input-Schichten auf STDIN.
Beginne ich den Prozess mit ProcessBuilder
-
ProcessBuilder pb = new ProcessBuilder(exe_path, " - ", image_save_path);
Process process = pb.start();
Nun ich bin nicht in der Lage, um herauszufinden, wie Rohr einen input-stream zu diesem Prozess.
Ich habe eine Vorlage-Datei Lesen, in eine DataInputStream
, und ich bin mit dem anfügen eine Zeichenfolge an das Ende:
DataInputStream dis = new DataInputStream (new FileInputStream (currentDirectory+"\\bin\\template.txt"));
byte[] datainBytes = new byte[dis.available()];
dis.readFully(datainBytes);
dis.close();
String content = new String(datainBytes, 0, datainBytes.length);
content+=" <body><div id='chartContainer'><small>Loading chart...</small></div></body></html>";
Wie kann ich die pipe content
zu den STDIN
des Prozesses?
UPDATE---
Folgenden die Antwort von Andrzej Doyle:
Habe ich die getOutputStream()
des Prozesses:
ProcessBuilder pb = new ProcessBuilder(full_path, " - ", image_save_path);
pb.redirectErrorStream(true);
Process process = pb.start();
System.out.println("reading");
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(process.getOutputStream()));
bw.write(content);
Dadurch erhalten Sie eine Fehlermeldung sagen:
Exception in thread "main" java.io.IOException: The pipe has been ended
2. UPDATE--------
Den aktuellen code-block ist als solcher:
try {
ProcessBuilder pb = new ProcessBuilder(full_path, "--crop-w", width, "--crop-h", height, " - ", image_save_path);
System.out.print(full_path+ "--crop-w"+ width+ "--crop-h"+ height+" "+ currentDirectory+"temp.html "+ image_save_path + " ");
pb.redirectErrorStream(true);
Process process = pb.start();
process.waitFor();
OutputStream stdin = process.getOutputStream();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(stdin));
//content is the string that I want to write to the process.
writer.write(content);
writer.newLine();
writer.flush();
writer.close();
} catch (Exception e) {
System.out.println("Exception: " + e);
e.printStackTrace();
}
Läuft der obige code gibt mir eine IOException: The pipe is being closed.
Was muss ich sonst noch tun, um das Rohr zu öffnen?
- Sollten Sie sich nicht bewegen, pb.starten Sie am Ende des Programms? (nach bw.write(Inhalt); Nur eine Vermutung, basierend auf "wie schreiben wir zu einem Prozess, nachdem es begonnen hatte!"
- nun, ich denke, wir sollten einen Prozess starten, um den Ausgabestrom.
- Sie sind das schreiben von Daten in den Ausgabestrom übersetzt "Ihr schreiben von Daten in den Prozess!" Wenn Sie möchten, um den Ausgang des Prozesses dann sollten Sie das tun Prozess.getInputStream und dann Lesen Sie es
- Lesen Sie die Fehler-stream? Vielleicht ist der Teilprozess emittiert einen Fehler und Abbruch. Wenn Sie nicht Lesen die Fehler stream, wirst du nie wissen.
- Ich finde
getOutputStream
einem sehr nicht-expliziten Namen für den eigentlichen Zweck : Gibt den output-stream mit dem normalen input des teilprozesses. Ausgabe der stream wird über eine Pipe in die Standardeingabe des Prozesses vertreten durch das Prozess-Objekt. In python ist es einfach alsstdin
aber dann könnte man argumentieren, dass das schreiben etwas namensstdin
ist nicht semantisch korrekt.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Entfernen Sie die Leerzeichen aus
" - "
-- die normalen Leerzeichen werden entfernt, indem der shell-parser, aber hier in derProcessBuilder
interpretiert als die (wörtlich) mit dem Namen beginnt und endet mit einem Leerzeichen.(Eigentlich auf der Suche auf den Prozess-output wie von Peter vorgeschlagen würde wahrscheinlich gesagt haben, Sie so...)
Dies bedeutet, dass der Prozess, den Sie begonnen haben, ist gestorben. Ich schlage vor, Sie Lesen die Ausgabe zu sehen, warum. z.B. hat es Ihnen einen Fehler.
waitFor
Befehl:process.waitFor();
java.io.BufferedReader@2512b853
readLine()
und drucken das aus.Gibt es einen Grund, Sie mit DataInputStream zum Lesen einer einfachen text-Datei? Aus der Java-Dokumentation
Es ist möglich, dass Sie das Lesen der Datei bewirkt ein EOF gesendet werden, um den Ausgabestrom verursacht die Pfeife zu Ende, bevor er Ihren string.
Sie Vorgaben zu sein scheint, Lesen Sie die Datei einfach Anhängen, um es vor der übergabe an das wkhtmltoimage-Prozess.
Du bist auch fehlt eine Anweisung zum schließen der Ausgabestrom an den Prozess. Dadurch wird der Prozess warten (hängt), bis es ein EOF-Zeichen aus dem Eingabe-stream, der wäre nie.
Ich würde empfehlen, mit einem BufferedReader statt, und schreiben es direkt in den Ausgabestrom vor dem anfügen Ihre zusätzlichen string. Dann rufen Sie close() auf den stream schließen.
Nachdem Sie die
Process
Objekt, rufen SiegetOutputStream()
, um zu ergattern ein stream, der sendet seine Inhalte an den Prozess-standard-input.Haben Sie halt diese können Sie verwenden, Java standard IO zu schreiben, was bytes, die dieser Strom Sie wollen (einschließlich wickelte Sie in ein Writer, hinzufügen von Puffern, etc.) - und, wie Sie schreiben, werden Sie Lesen, indem Sie den Prozess, sobald Sie geleert.
getOutputStream
und das schreiben auf den Prozess aus einem Puffer. Mache ich es richtig? Ich habe aktualisiert die Frage.Der folgende code funktioniert ebenso:
Hier stdinecho.cpp ist das Programm, das die Ausgänge der Linie trat auf seine Aufforderung: