天天看點

關于Java調用python腳本

1.使用Runtime.getRuntime().exec調用

腳本調用工具類

// python虛拟環境路徑
private static final String PYTHON_PATH = (String) PropertiesUtil.get("python-virtual-address");
// 日志類
private static final Logger LOGGER = LoggerFactory.getLogger(CallPyUtils.class);
/**
 * 調用python檔案
 *
 * @param filePath 檔案絕對路徑
 * @param args     要傳遞給python程式的參數
 * @return python列印的json資料
 */
public static List<String> callPy(String filePath, String[] args) {
    List<String> result = new ArrayList<>();
    try {
        // 前面為python虛拟環境路徑和python程式路徑
        List<String> args1 = Stream.of(PYTHON_PATH, filePath).collect(Collectors.toList());
        // 将要傳遞給python檔案的參數添加到字元串清單
        args1.addAll(Stream.of(args).collect(Collectors.toList()));
        String allArgs = String.join(" ", args1);
        // 執行py檔案
        LOGGER.info("開始執行python檔案: 檔案路徑{}, 執行參數{}", filePath, allArgs);
        // allArgs的格式為(虛拟環境路徑 python檔案路徑 傳遞的參數)
        Process proc = Runtime.getRuntime().exec(allArgs);

        // 輸入流和錯誤流的讀取順序不能變,否則會導緻程式一直等待
        // 用輸入輸出流來截取結果
        BufferedReader in = new BufferedReader(new InputStreamReader(proc.getInputStream(), StandardCharsets.UTF_8));
        // 擷取資料并将其執行個體化
        result = in.lines().collect(Collectors.toList());

        // 擷取錯誤流
        BufferedReader error = new BufferedReader(new InputStreamReader(proc.getErrorStream(), StandardCharsets.UTF_8));
        String err;
        while ((err = error.readLine()) != null) {
            LOGGER.error("調用python腳本錯誤, 路徑為{}, 錯誤資訊為: {}", filePath, err);
        }
        LOGGER.info("python檔案執行完成: 檔案路徑{}", filePath);
        in.close();
        proc.waitFor();
    } catch (Exception e) {
        LOGGER.error("調用python腳本錯誤", e);
    }
    return result;
}
           

python腳本示例

import sys
# 從指令行擷取輸入的參數,并将其列印到輸出流,以供Java讀取
print(sys.argv[1], sys.argv[2], sys.argv[3])
# 手動輸出錯誤流的方法,python發生錯誤時會自動将報錯列印到錯誤流中
# sys.stderr.write("這是錯誤流")
           

調用腳本代碼示例

// py檔案位址
private static final String filePath = "python檔案路徑";
// 設定需要傳入的參數
String[] args = new String[]{"需要傳入的參數"};
// 調用python腳本,擷取輸出流
List<String> strings = callPy(filePath, args);