很多朋友都想知道java怎么調python?下面就一起來了解一下吧~
java調python主要有兩種方法:1.使用Runtime.getRuntime()執行腳本文件;2. 將python腳本寫成進程為java提供服務,下面是具體的方法介紹:
第一種:使用Runtime.getRuntime()執行腳本文件
先建立python腳本文件 demo.py
import?numpy?as?np a?=?np.arange(12).reshape(3,4)print(a)
java調用python程序并輸出該結果
import?java.io.BufferedReader;import?java.io.IOException;import?java.io.InputStreamReader;public?class?Demo?{ ????public?static?void?main(String[]?args)?{ ????????//?TODO?Auto-generated?method?stub ????????Process?proc; ????????try?{ ????????????proc?=?Runtime.getRuntime().exec("python?D:\\demo.py");//?執行py文件 ????????????//用輸入輸出流來截取結果 ????????????BufferedReader?in?=?new?BufferedReader(new?InputStreamReader(proc.getInputStream())); ????????????String?line?=?null; ????????????while?((line?=?in.readLine())?!=?null)?{ ????????????????System.out.println(line); ????????????} ????????????in.close(); ????????????proc.waitFor(); ????????}?catch?(IOException?e)?{ ????????????e.printStackTrace(); ????????}?catch?(InterruptedException?e)?{ ????????????e.printStackTrace(); ????????}? ????}}
如若向python程序中函數傳遞參數并執行出結果,下面就舉一例來說明一下。同樣建立python腳本文件demo2.py
import?sys def?func(a,b): ????return?(a+b)if?__name__?==?'__main__': ????a?=?[] ????for?i?in?range(1,?len(sys.argv)): ????????a.append((int(sys.argv[i]))) ????print(func(a[0],a[1]))
其中sys.argv用于獲取參數url1,url2等。而sys.argv[0]代表python程序名,所以列表從1開始讀取參數。以上代碼實現一個兩個數做加法的程序,下面看看在java中怎么傳遞函數參數,代碼如下:
int?a?=?18;int?b?=?23;try?{ ????String[]?args?=?new?String[]?{?"python",?"D:\\demo2.py",?String.valueOf(a),?String.valueOf(b)?}; ????Process?proc?=?Runtime.getRuntime().exec(args);//?執行py文件 ????BufferedReader?in?=?new?BufferedReader(new?InputStreamReader(proc.getInputStream())); ????String?line?=?null; ????while?((line?=?in.readLine())?!=?null)?{ ????????System.out.println(line); ????} ????in.close(); ????proc.waitFor();}?catch?(IOException?e)?{ ????e.printStackTrace();}?catch?(InterruptedException?e)?{ ????e.printStackTrace();}
其中args是String[] { “python”,path,url1,url2 }; ,path是python程序所在的路徑,url1是參數1,url2是參數2,以此類推。
2. 將python腳本寫成進程為java提供服務
python腳本文件如下:
import?socketimport?sysimport?threadingimport?numpy?as?npfrom?PIL?import?Imagedef?main(): ????#?創建服務器套接字 ????serversocket?=?socket.socket(socket.AF_INET,socket.SOCK_STREAM) ????#?獲取本地主機名稱 ????host?=?socket.gethostname() ????#?設置一個端口 ????port?=?12345 ????#?將套接字與本地主機和端口綁定 ????serversocket.bind((host,port)) ????#?設置監聽最大連接數 ????serversocket.listen(5) ????#?獲取本地服務器的連接信息 ????myaddr?=?serversocket.getsockname() ????print("服務器地址:%s"%str(myaddr)) ????#?循環等待接受客戶端信息 ????while?True: ????????#?獲取一個客戶端連接 ????????clientsocket,addr?=?serversocket.accept() ????????print("連接地址:%s"?%?str(addr)) ????????try: ????????????t?=?ServerThreading(clientsocket)#為每一個請求開啟一個處理線程 ????????????t.start() ????????????pass ????????except?Exception?as?identifier: ????????????print(identifier) ????????????pass ????????pass ????serversocket.close() ????passclass?ServerThreading(threading.Thread): ????#?words?=?text2vec.load_lexicon() ????def?__init__(self,clientsocket,recvsize=1024*1024,encoding="utf-8"): ????????threading.Thread.__init__(self) ????????self._socket?=?clientsocket ????????self._recvsize?=?recvsize ????????self._encoding?=?encoding????????pass ????def?run(self): ????????print("開啟線程.....") ????????try: ????????????#接受數據 ????????????msg?=?'' ????????????while?True: ????????????????#?讀取recvsize個字節 ????????????????rec?=?self._socket.recv(self._recvsize) ????????????????#?解碼 ????????????????msg?+=?rec.decode(self._encoding) ????????????????#?文本接受是否完畢,因為python?socket不能自己判斷接收數據是否完畢, ????????????????#?所以需要自定義協議標志數據接受完畢 ????????????????if?msg.strip().endswith('over'): ????????????????????msg=msg[:-4] ????????????????????break ??????????? ????????????sendmsg?=?Image.open(msg) ????????????#?發送數據 ????????????self._socket.send(("%s"%sendmsg).encode(self._encoding)) ????????????pass ????????except?Exception?as?identifier: ????????????self._socket.send("500".encode(self._encoding)) ????????????print(identifier) ????????????pass ????????finally: ????????????self._socket.close()? ????????print("任務結束.....") ???????? ????????pass ????def?__del__(self): ????????passif?__name__?==?"__main__": ????main()
在java代碼中訪問python進程的代碼:
package?hello;import?java.lang.System;import?java.io.BufferedReader;import?java.io.IOException;import?java.io.InputStreamReader;import?java.net.InetAddress;import?java.net.Socket;import?java.io.OutputStream;import?java.io.PrintStream;import?java.io.InputStream;public?class?hello?{ ????public?static?void?main(String[]?args){ ????????//System.out.println("Hello?World!"); ????????//?TODO?Auto-generated?method?stub ????????try?{ ????????????InetAddress?addr?=?InetAddress.getLocalHost(); ????????????String?host=addr.getHostName(); ????????????//String?ip=addr.getHostAddress().toString();?//獲取本機ip ????????????//log.info("調用遠程接口:host=>"+ip+",port=>"+12345); ????????????//?初始化套接字,設置訪問服務的主機和進程端口號,HOST是訪問python進程的主機名稱,可以是IP地址或者域名,PORT是python進程綁定的端口號 ????????????Socket?socket?=?new?Socket(host,12345); ????????????//?獲取輸出流對象 ????????????OutputStream?os?=?socket.getOutputStream(); ????????????PrintStream?out?=?new?PrintStream(os); ????????????//?發送內容 ????????????out.print(?"F:\\xxx\\0000.jpg"); ????????????//?告訴服務進程,內容發送完畢,可以開始處理 ????????????out.print("over"); ????????????//?獲取服務進程的輸入流 ????????????InputStream?is?=?socket.getInputStream(); ????????????BufferedReader?br?=?new?BufferedReader(new?InputStreamReader(is,"utf-8")); ????????????String?tmp?=?null; ????????????StringBuilder?sb?=?new?StringBuilder(); ????????????//?讀取內容 ????????????while((tmp=br.readLine())!=null) ????????????????sb.append(tmp).append('\n'); ????????????System.out.print(sb); ????????????//?解析結果 ????????????//JSONArray?res?=?JSON.parseArray(sb.toString()); ????????}?catch?(IOException?e)?{ ????????????e.printStackTrace(); ????????}finally?{ ????????????try?{if(socket!=null)?socket.close();}?catch?(IOException?e)?{} ????????????System.out.print("遠程接口調用結束."); ????????} ??????}}
以上就是小編今天的分享,希望可以幫到大家。