我使用以下代码通过命令提示符
运行终端命令String[] command =
{
"zsh"
};
Process p = Runtime.getRuntime().exec(command);
new Thread(new SyncPipe(p.getErrorStream(), b)).start();
new Thread(new SyncPipe(p.getInputStream(), b)).start();
PrintWriter stdin = new PrintWriter(p.getOutputStream());
stdin.println("source ./taxenv/bin/activate");
stdin.println("python runner.py");
stdin.close();
int returnCode = 0;
try {
returnCode = p.waitFor();
String path2 = b + "/logs.txt"; // I am getting b value passed in from gc.jsp
if(new File(path2).exists())
{
BufferedReader reader = new BufferedReader(new FileReader(path2));
while ((line1 = reader.readLine()) != null)
{
content= content + line1 +"<br>";
}
reader.close();
request.setAttribute("logs", content);
RequestDispatcher rd = request.getRequestDispatcher("gc.jsp");
rd.forward(request, response);
}
}
catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Return code = " + returnCode +b);
}
class SyncPipe implements Runnable
{
public SyncPipe(InputStream istrm, String c) {
istrm_ = istrm;
b_ = c;
}
@SuppressWarnings("unused")
public void run() {
try
{
final byte[] buffer = new byte[1024];
for(int length = 0; (length = istrm_.read(buffer)) != -1; )
{
str = str + IOUtils.toString(istrm_, "UTF-8") + b_;
}
System.out.println(str);
String location = b_ + "/" + "logs.txt";
File file = new File(location);
if(!file.exists())
{
file.createNewFile();
}
FileWriter fw = new FileWriter(file.getAbsoluteFile());
BufferedWriter bw = new BufferedWriter(fw);
bw.write(str);
bw.close();
}
catch (Exception e)
{
e.printStackTrace();
}
}
private final InputStream istrm_;
private final String b_;
当我运行此代码时,我希望将其重定向到gc.jsp,但它显示如下
现在,当我刷新上面的页面时,我按预期获得输出,如下所示。
为什么会发生这种情况,我该如何解决?
============================= EDIT ================= =========
我添加了
bw.close() //Closing bufferedwriter
fw.close() //Closing file writer
仍然没有用。
现在,我添加了
TimeUnit.SECONDS.sleep(5);
这适用于小文件,所以基本上问题是来自行
的代码String path2 = b +“/ logs.txt”;
必须等待进程p完成。
我该怎么做?
答案 0 :(得分:1)
您的问题是您在SyncPipe
完成文件写入之前尝试阅读文件。您可以通过等待所有线程完成(join()
)
Process p = Runtime.getRuntime().exec(command);
Thread threadError = new Thread(new SyncPipe(p.getErrorStream(), b));
Thread threadInput = new Thread(new SyncPipe(p.getInputStream(), b));
threadError.start();
threadInput.start();
/* writing to process */
// wait until your process finished
p.waitFor();
// wait for both threads until they finished writing to files
threadError.join();
threadInput.join();
// read your files
说明:由于进程p
已停止,因此当Input / ErrorStream关闭时,您的SyncPipe线程将停止。然后它会将所有内容写入文件并正确关闭文件。之后,Thread正确停止。
join
方法告诉主线程(join
的调用者)等待线程停止(加入的被调用者,例如threadError)。 waitFor
有点等同于join
。
之后,您可以确定所有线程都已正确停止(p
,threadError
和threadInput
),因此所有文件都写入磁盘。现在你可以阅读它们了。