java代码调用Python代码

1,使用runtime调用Python脚本,(这里数据过大会显示文件名太长)

String[] arguments = new String[]{
                "E:\\Program Files\\python.exe",
                "E:\\wzCode\\signal.py",
                Arrays.toString(datas),
                String.valueOf(Num)};
            // 执行py文件,注意:这里的命令都最好用绝对路径,到底用哪一个环境的下的Python,比如env下面的tf2的环境;具体执行哪个python文件,也是绝对路径
            Process proc = Runtime.getRuntime().exec(arguments);

1.1 ,传参不能传递数组[],这样只是传递了地址值。

1.2,将数组格式转换为List类型,转换为String,但是会显示文件名称过长

复制代码
ava.io.IOException: Cannot run program "E:\Program Files\python.exe": CreateProcess error=206, 文件名或扩展名太长。
    at java.lang.ProcessBuilder.start(ProcessBuilder.java:1048)
    at java.lang.Runtime.exec(Runtime.java:620)
    at java.lang.Runtime.exec(Runtime.java:485)
    at com.weizu.common.utils.file.FileReaderScheduler.parse(FileReaderScheduler.java:162)
    at com.weizu.common.utils.file.FileReaderScheduler.lambda$paroseDocutment$0(FileReaderScheduler.java:91)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.runAndReset$$$capture(FutureTask.java:308)
    at java.util.concurrent.FutureTask.runAndReset(FutureTask.java)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)
Caused by: java.io.IOException: CreateProcess error=206, 文件名或扩展名太长。
    at java.lang.ProcessImpl.create(Native Method)
    at java.lang.ProcessImpl.<init>(ProcessImpl.java:386)
    at java.lang.ProcessImpl.start(ProcessImpl.java:137)
    at java.lang.ProcessBuilder.start(ProcessBuilder.java:1029)
    ... 12 more
复制代码

2,换种其他方式传递参数

2.1 使用byte字节数组格式传递大量参数。

2.1.1java

复制代码
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;

public static void main(String[] args) throws IOException {
// 创建一个包含double类型数据的列表
List<Double> data = new ArrayList<>();
for (double i = 1; i < 300; i++) data.add(i);

// 将double类型的数据序列化为字节数组
ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
DataOutputStream dataOut = new DataOutputStream(byteOut);
for (double d : data) {
dataOut.writeDouble(d);
}
byte[] dataBytes = byteOut.toByteArray();
Integer a = 123;
Integer b = 456;
Integer c = 789;
Integer d = 101112;
String[] cmd = {"E:\\Program Files\\python.exe", "E:\\wzCode\\testing.py", a.toString(), b.toString(), c.toString(), d.toString()};
// 将字节数组写入标准输入流
Process p = Runtime.getRuntime().exec(cmd);
p.getOutputStream().write(dataBytes);
p.getOutputStream().close();

// 读取 Python 脚本的输出结果
BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
System.out.println(line);
}
in.close();
}

}
复制代码

2.1.2Python代码

复制代码
import sys
import struct
import array
# 从标准输入中读取字节数据
print(sys.argv)
data_bytes = sys.stdin.buffer.read()

# 计算double类型数据的字节数
double_size = struct.calcsize('d')

# 按照big-endian字节顺序解析double类型数据
data_array = array.array('d')
for i in range(0, len(data_bytes), double_size):
    double_bytes = data_bytes[i:i+double_size]
    data_array.append(struct.unpack('>d', double_bytes)[0])

# 将double类型的数据转换为float类型的数据,并将其打印为十进制的double数组
 print("[", end="")
 for i, d in enumerate(data_array):
     if i > 0:
         print(", ", end="")
     print("{:.7g}".format(d), end="")
 print("]")  
######################
prameters = []
for i in range(1, len(sys.argv)):
    prameters.append(eval(sys.argv[i]))
result = Fre_integral(data_array, prameters[0],prameters[1],prameters[2],prameters[3],prameters[4])
print(result) 
复制代码

2.2 将数据保存读取后写入文件,调用Python脚本读取数据,执行算法返回参数。

2.2.1java

复制代码
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
public static void main(String[] args) throws IOException {
// 创建数据文件
String fileName = "data.txt";
FileWriter writer = new FileWriter(fileName);
for (double i = 0; i < 1000000; i++) {
writer.write(Double.toString(i) + "\n");
}
writer.close();

// 执行 Python 脚本,并传递数据文件名作为参数
String[] cmd = {"python", "script.py", fileName};
Process p = Runtime.getRuntime().exec(cmd);

// 读取 Python 脚本的输出结果
BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
System.out.println(line);
}
in.close();
}
}
复制代码

2.2,2python

复制代码
import sys
import numpy as np

def process_data(data_file):
    # 从数据文件中读取数据
    data = np.loadtxt(data_file)
    
    # 在这里处理数据,例如调用你的算法函数
    result = np.mean(data)
    
    # 返回处理结果
    return result

if __name__ == '__main__':
    # 将命令行参数解析为数据文件名
    data_file = sys.argv[1]
    
    # 处理数据
    result = process_data(data_file)
    
    # 输出结果
    print(result)
复制代码

 二,使用http调用

1,电脑安装Flask服务,在Python编写flask接口,Java端使用RestTemplate请求接口

复制代码
from flask import Flask, request, jsonify
import numpy as np

app = Flask(__name__)

@app.route('/test', methods=['GET', 'POST'])
def home():
    if request.method == 'POST':
        x = request.form.get('data')  # 获取 POST 请求中的数据
        fs = float(request.form.get('fs'))  # 获取采样频率
        x = np.array(eval(x))  # 将输入的数据字符串解析为数组
        f, mag = myfft(x, fs)  # 调用 myfft 函数进行傅里叶变换
        result = {"f": f.tolist(), "mag": mag.tolist()}  # 将 f 和 mag 转
        return jsonify(result)  # 以 JSON 格式返回字典
    return "meide"

def myfft(x, fs):
    """对信号进行傅里叶变化"""
    m_N = len(x)
    t = np.arange(0, m_N) / fs
    y = np.fft.fft(x - x.mean(), m_N)
    mag = abs(y) * 2 / m_N
    f = np.arange(0, m_N) * fs / m_N
    return f, mag

if __name__ == '__main__':
    app.run()
复制代码

Java端

复制代码
 /**
     * 读取本地文件,发送请求到http
     * 通过http方法调用Python
     */

    @GetMapping("/getPython")
    public void porseJSON() {
        //获取本地文件
        String pathUrl1 = "E:\\wzCode\\phm\\channeldata\\20230907085126\\ACCZDATA\\20230907085126.txt";
        List<Double> objects1 = porseString(pathUrl1);
        //发送resttemplate


        // 创建RestTemplate实例
        RestTemplate restTemplate = new RestTemplate();

        // 设置请求头
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

        // 设置请求体参数
        MultiValueMap<String, Object> requestBody = new LinkedMultiValueMap<>();
        requestBody.add("data", objects1.toString());
        requestBody.add("fs", "4800");

        // 创建HttpEntity对象,将请求体和请求头组合起来
        HttpEntity<MultiValueMap<String, Object>> entity = new HttpEntity<>(requestBody, headers);

        // 发送POST请求
        ResponseEntity<String> response = restTemplate.exchange("http://127.0.0.1:5000/test", HttpMethod.POST, entity, String.class);
        System.out.println(response.toString());
    }

    public static List<Double> porseString(String pathUrl) {
        List<Double> numbers = new ArrayList<>();
        File file = new File(pathUrl);
        try (BufferedReader bufferedReader = new BufferedReader(new FileReader(pathUrl))) {

            String s = bufferedReader.readLine();
            if (StringUtils.isNotBlank(s)) {
                numbers = Stream.of(s.split("#")).map(Double::parseDouble).collect(Collectors.toList());
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return numbers;
    }
复制代码

 

posted @   党王  阅读(917)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· 葡萄城 AI 搜索升级:DeepSeek 加持,客户体验更智能
· 什么是nginx的强缓存和协商缓存
· 一文读懂知识蒸馏
点击右上角即可分享
微信分享提示