JAVA web呼叫執行python指令碼程式的四種方式,迴避java.lang.OutOfMemoryError:PermGen space記憶體溢位問題
阿新 • • 發佈:2019-02-14
我在網上搜到的JAVA呼叫python程式的三種方式:
方式一:呼叫python函式。可以傳入引數,獲取返回值。
方式二:直接執行python指令碼。不能傳參,不能獲取返回值。public static void PythonFunctionTest(){ //python 直譯器 PythonInterpreter interpreter = new PythonInterpreter(); interpreter.execfile("E:\\Python_code\\helloPython.py"); PyFunction func=(PyFunction)interpreter.get("adder", PyFunction.class); int a=2010; int b=2; PyObject pyobj = func.__call__(new PyInteger(a), new PyInteger(b)); System.out.println("answer= "+pyobj.toString()); }
public static void PythonTextTest()
{
PythonInterpreter interpreter = new PythonInterpreter();
interpreter.execfile("E:/Python_code/helloPython1.py");
}
方式三:在JAVA程式碼裡面直接寫python程式,直接執行。這種方法顯然可以把引數傳進去,但是能不能獲得返回值需要進一步研究。
考慮了一下,因為第一種方式可以以呼叫函式的形式,同時即可以傳參又可以獲取返回值,所以我選擇了第一種方式用於在JAVA程式碼塊中執行python程式。我在單獨的一個JAVA程式中執行相應程式碼時,沒有問題,可以傳參也可以獲得返回的結果。但是當我把這段程式碼放到現有的JAVAWEB的程式中時,會出現public static void PythonTest(){ PythonInterpreter interpreter =new PythonInterpreter(); interpreter.exec("days=('Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sunday')"); interpreter.exec("print days[0]"); }
java.lang.OutOfMemoryError:PermGen space記憶體溢位的問題。
於是我又按照網上的方法增到tomcat和eclipse的記憶體,結果無效。就這樣卡了很久後,我找到了第四種執行python程式的方法,這個方法不會產生記憶體溢位的問題。
方式四:使用控制檯執行python指令碼,可以傳參和獲取返回值。
public static String runTimeMethod(String name,String path) {
try {
String cmd="python E:\\Python_code\\settingTest.py "+name+" "+path;
Process pr = Runtime.getRuntime().exec(cmd);
BufferedReader in = new BufferedReader(new InputStreamReader(
pr.getInputStream()));
String line="";
//輸出列印在控制檯上的結果
// while ((line = in.readLine()) != null) {
// System.out.println(line);
// }
//得到列印在控制檯上的結果
while ((line = in.readLine()) != null) {
result+=line;
}
in.close();
pr.waitFor();
// System.out.println("end");
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
其實這種方法就是在JAVA程式中執行控制檯命令,其效果等同於把python E:\\Python_code\\settingTest.py arg1 arg2
這段命令拷貝到cmd控制檯中。雖然可以傳入引數或獲取返回值,但其實它的實現並不是特別靈活和好用。下面是我用於測試的python程式碼。
#coding=utf-8
import json
import sys
def JsonTestForDownloadApks(name,path):
print name,' ',path
name=sys.argv[1]
path=sys.argv[2]
JsonTestForDownloadApks(name,path)
可以看出,傳入引數的實現是通過python程式獲取控制檯輸入的方式。sys.arg[0]是當前python程式的執行路徑,sys.arg[1],sys.arg[2]是我們輸入的第一,二個引數。獲取返回結果是通過獲取列印到控制檯的輸出流獲的方式。其實這種方式有很大的侷限性,但是它起碼能迴避讓我頭疼的記憶體溢位問題,也能滿足我目前的功能需求,所以我選擇了這種方式。PS.因為我對python的知識幾乎一無所知,對於python和JAVA之間的呼叫也是現學現用,所以我上面所說的方法可能非常低階甚至存在很大的風險,僅供大家參考。