java调用脚本语言或其他进程(以Python为例)
2017-04-07 01:30
543 查看
很多时候,我们往往需要在java中调用其他脚本语言,或者是其他进程,来弥补java的一些不便之处.
万能的方式就是使用Process类了,当然针对Python还可以使用jython,但jython还是有诸多不便
Process的强大功能,就在于调用其他进程时,可以相互实现信息传递,基于java IO实现,调用者只需要熟悉java IO操作,即可调用.
我写了一个辅助类,以便于对进程之间的信息传递,实现策略为,将InputStream操作改为线程操作.具体代码如下:
这个便是辅助类啦,类如其名”进程IO传输”,不过准确来讲,已经实现进程简单管理了.
可以随心所欲的在java和脚本之间传递数据,贼爽啊!
最后我们测试一下吧:
测试的Python代码如下
测试结果:
当然,由于进程或者脚本等待着输入,而java迟迟不给输出,那么java的子线程stin,sterr也不会结束,我们将得不到脚本或进程的输出,而是得到null.此处,我没有设置抛出异常,而是把stin,sterr设置为了后台线程,当主线程结束,stin,sterr也随之终止,process也随之destroy掉,避免进程或脚本一直等待输入而持续运行.
万能的方式就是使用Process类了,当然针对Python还可以使用jython,但jython还是有诸多不便
String command = "python test.py"; Process pythonProcess = Runtime.getRuntime().exec(command);
Process的强大功能,就在于调用其他进程时,可以相互实现信息传递,基于java IO实现,调用者只需要熟悉java IO操作,即可调用.
我写了一个辅助类,以便于对进程之间的信息传递,实现策略为,将InputStream操作改为线程操作.具体代码如下:
package runtime; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; /** * 将InputStream操作改为线程操作 */ public class StreamThreadRead extends Thread{ //存储读取的字符串 private final StringBuffer sBuffer; //对应的输入流 private final InputStream iStream; public StreamThreadRead(InputStream iStream){ super(); sBuffer = new StringBuffer(); this.iStream = iStream; } @Override public void run() { BufferedReader bReader = new BufferedReader(new InputStreamReader(iStream)); String str; try { while ((str = bReader.readLine()) != null) { sBuffer.append(str).append("\n"); } } catch (IOException e) { e.printStackTrace(); } } public StringBuffer getsBuffer() { return sBuffer; } public InputStream getiStream() { return iStream; } }
这个便是辅助类啦,类如其名”进程IO传输”,不过准确来讲,已经实现进程简单管理了.
可以随心所欲的在java和脚本之间传递数据,贼爽啊!
package runtime; import java.io.BufferedWri 4000 ter; import java.io.IOException; import java.io.OutputStreamWriter; /** * 进程数据传输对象 */ public class ProcessIOTransport { private final BufferedWriter stout; private final StreamThreadRead stin; private final StreamThreadRead errin; private final Process process; /** * 构造一个ProcessIOTransport * @param process * @throws IOException */ public ProcessIOTransport(String command) throws IOException{ process = Runtime.getRuntime().exec(command); stout = new BufferedWriter(new OutputStreamWriter(process.getOutputStream())); stin = new StreamThreadRead(process.getInputStream()); errin = new StreamThreadRead(process.getErrorStream()); //设为后台线程 stin.setDaemon(true); errin.setDaemon(true); //启动线程 stin.start(); errin.start(); //监控进程 new Thread(new Runnable(){ @Override public void run() { while(stin.isAlive()||errin.isAlive()){ try { Thread.sleep(300); } catch (InterruptedException e) { e.printStackTrace(); } } process.destroy(); } }); } /** * 构造一个ProcessIOTransport,其中向进程中输入参数args * @param process * @param args * @throws IOException */ public ProcessIOTransport(String command,String...args) throws IOException{ this(command); write(args); } /** * 构造一个ProcessIOTransport,当前java线程等待进程运行结束 * @param process * @param timeOut 最迟等待时间(ms) * @throws IOException */ public ProcessIOTransport(String command,long timeOut) throws IOException{ this(command,timeOut,new String[]{null}); } /** * 构造一个ProcessIOTransport,当前java线程等待进程运行结束 * @param process * @param timeOut 最迟等待时间(ms) * @param args 向进程中传入的参数 * @throws IOException */ public ProcessIOTransport(String command,long timeOut,String...args) throws IOException{ this(command,args); long start = System.currentTimeMillis(); long now = System.currentTimeMillis(); while(now-start<timeOut&&(stin.isAlive()||errin.isAlive())){ try { Thread.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); } now = System.currentTimeMillis(); } } /** * 向process写数据 * @param args * @throws IOException */ public void write(String...args) throws IOException { for(int i = 0;i<args.length;i++){ if(args[i]!=null){ stout.write(args[i]); stout.flush(); } } } /** * 读取process的标准输出 * @return */ public String readStandard(){ if(stin.isAlive()){ return null; }else{ return stin.getsBuffer().toString(); } } /** * 读取process的错误输出 * @return */ public String readError(){ if(stin.isAlive()){ return null; }else{ return stin.getsBuffer().toString(); } } }
最后我们测试一下吧:
package runtime; import java.io.IOException; public class Test { public static void main(String[] args) { String command = "python test.py"; try { ProcessIOTransport piot1 = new ProcessIOTransport(command,200,"write1\n","write2\n"); ProcessIOTransport piot2 = new ProcessIOTransport(command,200,"write3\n"); System.out.println(piot1.readStandard()); System.out.println("---------------------"); System.out.println(piot2.readStandard()); } catch (IOException e) { e.printStackTrace(); } } }
测试的Python代码如下
#unicode=UTF-8 print ('hello') v = input() print (v) print ('xx') print (3+6) z = input() print (z) print (3+3+3+3+3+3+3+3+3+3/6+3+3+3+3)
测试结果:
hello write1 xx 9 write2 39.5 --------------------- null
当然,由于进程或者脚本等待着输入,而java迟迟不给输出,那么java的子线程stin,sterr也不会结束,我们将得不到脚本或进程的输出,而是得到null.此处,我没有设置抛出异常,而是把stin,sterr设置为了后台线程,当主线程结束,stin,sterr也随之终止,process也随之destroy掉,避免进程或脚本一直等待输入而持续运行.
相关文章推荐
- Java命令行调用Python(其实可以调用任何其他语言)
- python操作子进程,调用其他程序
- Java调用外部进程并拦截输入输出流--Java IDE Console解密(上篇)
- 在JAVA程序中调用其他程序
- java Runtime Process调用可执行文件,子进程阻塞
- java实现写入日志类,方便其他类中调用
- java程序与其他进程的数据通信
- 应用进程实现对其他应用程序的调用
- java调用CMD命令显示所有进程的信息
- WinExec,ShellExecute ,CreateProcess 调用其他进程,即开启其他exe程序
- 程序调用飞信API发送免费短信(JAVA例子,其他语言一样用)
- IO 输入与输出(9)-- Java程序与其他进程的数据通信
- 用C#调用Windows API和其他进程通信
- Java 调用外部进程
- java调用python的webservice
- python进程杀除及子程序调用
- Java调用外部进程并拦截输出流--Java IDE Console解密(下篇)
- Java调用外部进程并拦截输入输出流--Java IDE Console解密(下篇)
- 通过修改IAT挂钩其他进程的API调用
- JAVA高级视频_IO输入与输出 Java程序与其他进程的数据通讯 学习笔记