经常会遇到调用其它程序功能的业务需求,在java中通常有两种实现方法
runtime runtime = runtime.getruntime();process p = runtime.exec(cmd);
process p=new processbuilder(cmd).start();
process是一个抽象的类,它包含6个抽象的方法
abstract public outputstream getoutputstream();abstract public inputstream getinputstream();abstract public inputstream geterrorstream();abstract public int waitfor() throws interruptedexception;abstract public int exitvalue();abstract public void destroy();
process类提供获取子进程的输入流、子进程的输出流、子进程的错误流、等待进程完成、检查进程的推出状态以及销毁进程的方法;在这里需要提及的是创建的子进程没有自己的控制台或终端,其所有的io操作都是通过(输入流、输出流、错误流)重定向到父进程中。
我需要在linux下首先将一个文件copy到指定的文件夹下面,之后需要将该文件夹下面的文件加入指定的jar中,那么问题就来了,必须保证其先后顺序,也就书说再执行第二个命令的时候第一个命令必须完成。
public void cmd(string cmd){ try { process ps= runtime.getruntime().exec(cmd); } catch (exception e) { logger.info(e.getmessage(),e); } }
main函数如下:
public static void main(string[] args){ string copy="cp -rf "+source+" "+target; string jar="jar -uvf "+jar+" "+file; cmd(copy); cmd(jar);}
但是结果是新生成的jar中压根没有新加入的文件,但是文件确实copy到了指定的文件夹中,也就是谁两个命令都执行了,问题的关键就是“异步”,这时候需要waitfor()的介入
public void cmd(string cmd){ try { process ps= runtime.getruntime().exec(cmd); ps.waitfor(); } catch (exception e) { logger.info(e.getmessage(),e); } }
那么问题就解决了!
我在rvice中实现了process的调用。
string[] commands = { commandgenerate,commandpublish}; printwriter printwriter = respon.getwriter(); for (string comm : commands) { runtime runtime = runtime.getruntime(); try { logger.info("command is :{}",comm); process process = runtime.exec(comm, null, null); bufferedinputstream inputstream = new bufferedinputstream( process.getinputstream()); bufferedreader bufferedreader = new bufferedreader( new inputstreamreader(inputstream)); string line; while (bufferedreader.read() != -1) { line = bufferedreader.readline(); system.out.println(line); } bufferedreader.clo(); inputstream.clo(); printwriter.println("success"); } catch (ioexception e) { logger.error(e.getmessage(), e); printwriter.println(e.getmessage()); } } printwriter.flush(); printwriter.clo();
对应的controller为:
state state = new state(); string message=""; try { message = missionrvice.syntax(taskname, respon); } catch (interruptedexception e) { e.printstacktrace(); } state.tsuccess(true); state.tmessage(message.trim()); return state;
打印state.getmessage()确实可以获得值,但是state返回就是空,刚开始以为是ajax的timeout时间的问题:修改了ajax的timeout时间仍然不行;将message直接赋值,然thread等待20s,结果是可以返回的,所以问题最终定为于rvice的这段实现。
原因分析:在上面提及了,process创建的子进程没有自己的控制台或终端,其所有的io操作都是通过(输入流、输出流、错误流)重定向到父进程中,如果该可执行程序的输入、输出或者错误输出比较多的话,而由于运行窗口的标准输入、输出等缓冲区有大小的限制,则可能导致子进程阻塞,甚至产生死锁,其解决方法就是在waitfor()方法之前读出窗口的标准输出、输出、错误缓冲区中的内容。
for切线斜率 (string comm : commands) { logger.info("the comm time is:"+new date().gettime()+" the comm is:"+comm); runtime r春节联欢晚会2022节目单untime = runtime.getruntime(); process p=null; try { p = runtime.exec(comm ,null,null); final inputstream is1 = p.getinputstream(); final inputstream is2 = p.geterrorstream(); new thread() { public void run() { bufferedreader br1 = new bufferedreader(new inputstreamreader(is1)); try { string line1 = null; while ((line1 = br1.readline()) != null) { if (line1 != null){ logger.info("p.getinputstream:"+line1); if(line1.indexof("syntax check result:")!=-1){ builder.append(line1); } } } 弱相互作用 } catch (ioexception e) { e.printstacktrace(); } finally{ try { is1.clo(); } catch (ioexception e) { e.printstacktrace(); } } } }.start(); new thread() { public void run() { bufferedreader br2 = new bufferedreader(new inputstreamreader(is2)); try { 金融书籍 string line2 = null ; while ((line2 = br2.readline()) != null ) { if (line2 != null){ } } } catch (ioexception e) { e.printstacktrace(); } finally{ try { is2.clo(); } catch (ioexception e) { e.printstacktrace(); } } } }.start(); p.waitfor(); p.destroy(); } catch (exception e) { try{ p.geterrorstream().clo(); p.getinputstream().clo(); p.getoutputstream().clo(); } catch(exception ee){} } }
package cn.itcast.process;import java.io.bufferedreader;import java.io.ioexception;import java.io.inputstream;imp南有乔木ort java.io.inputstreamreader;import java.io.outputstream;public class processtest implements runnable{ private process process = null; public processtest() { try { process = runtime.getruntime().exec("java mytest"); new thread(this).start(); } catch (ioexception e) { e.printstacktrace(); } } public static void main(string[] args) { processtest processtest = new processtest(); processtest.nd(); } public void nd() { outputstream outputstream = process.getoutputstream(); while(true) { try { outputstream.write("this is good\r\n".getbytes()); } catch (ioexception e) { // todo auto-generated catch block e.printstacktrace(); } } } public void run() { inputstream inputstream = process.getinputstream(); bufferedreader bufferedreader = new bufferedreader(new inputstreamreader(inputstream)); string str = null; try { while(true) { str = bufferedreader.readline(); system.out.println(str); } } catch (ioexception e) { e.printstacktrace(); } }}
//理解下面这句话就能更加容易的理解上面的代码
在java程序中可以用process类的实例对象来表示子进程,子进程的标准输入和输出不在连接到键盘和显示器,而是以管道流的形式连接到父进程的
一个输出流和输入流对象上-à好好理解这句代码就能看懂那个程序。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持www.887551.com。
本文发布于:2023-04-04 02:57:25,感谢您对本站的认可!
本文链接:https://www.wtabcd.cn/fanwen/zuowen/a949f485cf231144dd417e517f19e221.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文word下载地址:Java中Process类的使用与注意事项说明.doc
本文 PDF 下载地址:Java中Process类的使用与注意事项说明.pdf
留言与评论(共有 0 条评论) |