Comment pipe InputStream à ProcessBuilder
Veuillez passer à la 2ème mise à jour. Je ne voulais pas changer le contexte précédent de cette question.
Je suis en utilisant wkhtmltoimage à partir d'une application Java.
Le niveau moyen de l'aide c'est - path-to-exe http://url.com/image.png
.
Selon leurs docs, si nous écrivons un -
au lieu d'une URL d'entrée, l'entrée se décale vers STDIN.
Je suis de commencer le processus à l'aide de ProcessBuilder
-
ProcessBuilder pb = new ProcessBuilder(exe_path, " - ", image_save_path);
Process process = pb.start();
Maintenant, je suis incapable de comprendre comment canaliser un flux d'entrée pour ce processus.
J'ai un fichier de modèle de lire dans un DataInputStream
, et je suis ajoutant une chaîne à la fin:
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>";
Comment puis-je pipe content
à la STDIN
du processus?
Mise à JOUR---
À la suite de la réponse par Andrzej Doyle:
J'ai utilisé le getOutputStream()
du processus:
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);
C'est une erreur de dire:
Exception in thread "main" java.io.IOException: The pipe has been ended
2e mise à JOUR--------
L'actuel bloc de code est comme suit:
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();
}
Exécute le code ci-dessus donne-moi un IOException: The pipe is being closed.
De quoi dois-je faire pour garder le tuyau ouvert?
eh bien, je pense que nous aurions besoin de lancer un processus en vue d'obtenir son outputstream.
Vous êtes l'écriture de données sur le outputstream ceci se traduit par "votre sont l'écriture des données dans le processus!" Si vous voulez obtenir à la sortie du processus, alors vous devriez le faire le processus.getInputStream et puis de le lire
Êtes-vous de lire le flux d'erreur? Peut-être le sous-processus émet une erreur et de se terminer. Si vous n'êtes pas lire le flux d'erreur, vous ne le saurez jamais.
Je trouve
getOutputStream
un très non-explicite nom de l'objet : Retourne le flux de sortie connectée à l'entrée normale de la sous-processus. De sortie pour le flux est canalisé dans l'entrée standard du processus représenté par ce Processus objet. En python, il est simplement appelé stdin
mais alors on pourrait dire que l'écriture de quelque chose qui s'appelle stdin
n'est pas sémantiquement correct.OriginalL'auteur Hrishikesh Choudhari | 2012-06-28
Vous devez vous connecter pour publier un commentaire.
Supprimer les espaces de
" - "
-- la normale des espaces sont supprimés par le shell de l'analyseur, mais ici, dans laProcessBuilder
, il est interprété comme l' (littérale) de nom de fichier commençant et se terminant par un espace.(En fait en regardant le processus de sortie comme Pierre l'a suggéré aurait probablement vous l'a dit...)
OriginalL'auteur ShiDoiSi
Cela signifie que le processus que vous avez commencé a mort. Je vous suggère de lire la sortie pour voir pourquoi. par exemple, avez-vous un message d'erreur.
J'ai aussi ajouté un
waitFor
commande:process.waitFor();
Je n'ai jamais vu un programme qui donne une erreur lorsque vous exécutez à partir de la ligne de commande.
J'ai trouvé cette sortie à partir de l'erreur:
java.io.BufferedReader@2512b853
Cela signifie que vous avez l'impression de l'BufferedReader objet au lieu de le lire avec
readLine()
et de l'impression.OriginalL'auteur Peter Lawrey
Est-il une raison pour laquelle vous êtes à l'aide de DataInputStream pour lire un simple fichier texte? À partir de la documentation de Java
Il est possible que la façon dont vous lisez le fichier provoque une EOF être envoyé à l'outputstream causant la pipe à la fin avant qu'il arrive à votre chaîne.
Les exigences que vous semble de lire le fichier à ajouter avant de les transmettre à la wkhtmltoimage processus.
Vous manque aussi une déclaration pour fermer la outputstream pour le processus. Cela entraînera le processus d'attente (se bloquer) jusqu'à ce qu'il obtienne une EOF depuis le flux d'entrée, ce qui serait jamais.
Je vous recommande d'utiliser un BufferedReader au lieu de cela, et de l'écrire directement à l'outputstream avant d'ajouter votre chaîne supplémentaire. Puis appeler close() pour fermer le flux de données.
OriginalL'auteur Rajesh J Advani
Après la création de la
Process
objet, vous pouvez appelergetOutputStream()
afin d'obtenir un flux qui envoie son contenu pour le processus de l'entrée standard.Une fois que vous avez la main sur ce que vous pouvez utiliser Java d'e /s standard à écrire ce octets dans le flux que vous voulez (y compris en l'enveloppant dans un Écrivain, l'ajout de tampon, etc.) - et comme vous l'écrivez, elles seront lues par le processus dès qu'ils sont vidées.
getOutputStream
, et l'écriture dans le processus de la mémoire tampon. Suis-je la faire correctement? J'ai mis à jour la question.OriginalL'auteur Andrzej Doyle
Le code suivant fonctionne ainsi:
Ici stdinecho.cpp le programme des sorties de la ligne sur son invite:
OriginalL'auteur Xolve