Hri*_*ari 8 java stdin processbuilder wkhtmltopdf java-io
请转到第二次更新.我不想改变此问题的先前背景.
我正在使用Java应用程序中的wkhtmltoimage.
使用它的标准方法是 - path-to-exe http://url.com/ image.png.
根据他们的文档,如果我们写一个-而不是输入URL,输入转移到STDIN.
我正在使用ProcessBuilder- 开始这个过程-
ProcessBuilder pb = new ProcessBuilder(exe_path, " - ", image_save_path);
Process process = pb.start();
Run Code Online (Sandbox Code Playgroud)
现在我无法弄清楚如何将输入流传递给此进程.
我有一个模板文件读入a DataInputStream,我在最后附加一个字符串:
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>";
Run Code Online (Sandbox Code Playgroud)
我怎么管content的STDIN过程中?
UPDATE ---
在Andrzej Doyle的回答之后:
我用过了getOutputStream()这个过程:
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);
Run Code Online (Sandbox Code Playgroud)
这样做会出错:
Exception in thread "main" java.io.IOException: The pipe has been ended
Run Code Online (Sandbox Code Playgroud)
第二次更新--------
当前的代码块是这样的:
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();
}
Run Code Online (Sandbox Code Playgroud)
运行上面的代码给了我一个 IOException: The pipe is being closed.
我还需要做些什么来保持管道畅通?
您是否有理由使用DataInputStream来读取简单的文本文件?来自Java文档
数据输入流允许应用程序以与机器无关的方式从底层输入流中读取原始Java数据类型
读取文件的方式可能会导致EOF被发送到输出流,导致管道在到达字符串之前结束.
您的要求似乎是在将文件传递给wkhtmltoimage进程之前简单地读取文件.
您还缺少关闭流程输出流的语句.这将导致进程等待(挂起),直到它从输入流中获得EOF,这将永远不会.
我建议使用BufferedReader,并在附加附加字符串之前将其直接写入输出流.然后调用close()关闭流.
ProcessBuilder pb = new ProcessBuilder(full_path, " - ", image_save_path);
pb.redirectErrorStream(true);
Process process = null;
try {
process = pb.start();
} catch (IOException e) {
System.out.println("Couldn't start the process.");
e.printStackTrace();
}
System.out.println("reading");
try {
if (process != null) {
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(process.getOutputStream()));
BufferedReader inputFile = new BufferedReader(new InputStreamReader(new FileInputStream(currentDirectory+"\\bin\\template.txt")));
String currInputLine = null;
while((currInputLine = inputFile.readLine()) != null) {
bw.write(currInputLine);
bw.newLine();
}
bw.write("<body><div id='chartContainer'><small>Loading chart...</small></div></body></html>");
bw.newLine();
bw.close();
}
} catch (IOException e) {
System.out.println("Either couldn't read from the template file or couldn't write to the OutputStream.");
e.printStackTrace();
}
BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()));
String currLine = null;
try {
while((currLine = br.readLine()) != null) {
System.out.println(currLine);
}
} catch (IOException e) {
System.out.println("Couldn't read the output.");
e.printStackTrace();
}
Run Code Online (Sandbox Code Playgroud)
删除其中的空格" - "——正常的空格被 shell 解析器删除,但在 中ProcessBuilder,它被解释为以空格开头和结尾的(文字)文件名。
(实际上,按照彼得的建议查看进程的输出可能会告诉你这一点......)