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();
}
// 创建一个包含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; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· 葡萄城 AI 搜索升级:DeepSeek 加持,客户体验更智能
· 什么是nginx的强缓存和协商缓存
· 一文读懂知识蒸馏