java调用脚本语言或其他进程(以Python为例)
来源:互联网 发布:聚财网络 编辑:程序博客网 时间:2024/06/16 19:10
很多时候,我们往往需要在java中调用其他脚本语言,或者是其他进程,来弥补java的一些不便之处.
万能的方式就是使用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.BufferedWriter;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)
测试结果:
hellowrite1xx9write239.5---------------------null
当然,由于进程或者脚本等待着输入,而java迟迟不给输出,那么java的子线程stin,sterr也不会结束,我们将得不到脚本或进程的输出,而是得到null.此处,我没有设置抛出异常,而是把stin,sterr设置为了后台线程,当主线程结束,stin,sterr也随之终止,process也随之destroy掉,避免进程或脚本一直等待输入而持续运行.
1 0
- java调用脚本语言或其他进程(以Python为例)
- 【干货】iData二次开发——以脚本语言Python为例
- python操作子进程,调用其他程序
- Java调用脚本语言(JavaScript)
- 在程序中调用其他进程或文档
- python调用Shell脚本(或其他脚本比如python)
- java调用matlab实例(以四则运算为例)
- C#中调用python脚本语言
- python灰帽子-修改其他进程中的函数调用参数
- python脚本调用c/c++库,以opencv的python接口为例
- 使用visualvm远程监控java进程(以hadoop进程为例)
- Java动态调用脚本语言Groovy
- 将python或R生成的模型存为PMML供java调用
- 利用shell或其他脚本语言在Apache下写CGI
- 以tcl脚本语言+mysql DB 为例 介绍ETL调度系统搭建过程
- f2py支持在fortran语言中调用其他Fortran函数或C代码或Python代码
- f2py支持在fortran语言中调用其他Fortran函数或C代码或Python代码
- flex调用webservice(以天气预报为例)
- Servlet中的GET和POST之间的区别
- Java03-while语句,for语句、函数
- 算法- 带分数(java)
- angular基本概念
- 线程池
- java调用脚本语言或其他进程(以Python为例)
- 浅谈JS __proto__与prototype的联系与区别
- MatLab之父:编程实践学习笔记(一)--迭代
- KETTLE作业/转换在linux下的稳定执行
- TCP传输
- 蓝桥杯2017官方模拟赛 还款计算(思路)
- TCP传输2
- C# rdlc 报表学习总结
- 为什么10M、20M的宽带只有大约1、2M的下载速度——网速KB/s与Kbps(Kb/s)的区别