将数据(字符串列表)从Java程序传递到Python脚本的首选方法是什么。 python脚本对数据执行一些处理,然后我需要将结果返回到我的Java程序中。
是否有一个框架可以让您轻松完成此操作?
编辑:更具体的要求。
我的Java程序是一个调度程序(运行每X分钟和Y秒)连接到外部服务并获取RAW数据并将其发送到python。
我可以用Python重写所有内容,但这需要花费我很多时间。我在寻找是否有办法重用我已有的东西。
我想使用现有的Python脚本,只需要很少的更改。我的python脚本使用了一堆外部库(例如,numpy) 从Java传递到Python的数据是Json格式,Python返回的数据也是Json。
使用套接字是一个选项,但我要运行服务器进程。
答案 0 :(得分:3)
Python代码:
import StringIO
import re
import select
import socket
import sys
import threading
class IPC(threading.Thread):
def __init__(self, line_filter = None):
threading.Thread.__init__(self)
self.daemon = True
self.lock = threading.Lock()
self.event = threading.Event()
self.event.clear()
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.recv_buffer_size = 8192
self.buffer = StringIO.StringIO()
if(line_filter == None):
self.line_filter = lambda x: x
else:
self.line_filter = line_filter
def run(self):
self.sock.connect(("localhost", 32000))
data = True
while data:
try:
data = self.sock.recv(self.recv_buffer_size)
except socket.error, e:
print e
self.sock.close()
break
self.lock.acquire()
self.buffer.write(data)
self.lock.release()
self.event.set()
def readlines(self):
self.lock.acquire()
self.buffer.seek(0)
raw_lines = self.buffer.readlines()
self.buffer.truncate(0)
self.lock.release()
lines = map(self.line_filter, raw_lines)
return lines
proc_control = IPC()
while True:
proc_control.event.wait()
data = proc_control.readlines()
if(data):
# Do Stuff
proc_control.event.clear()
Java代码:
SocketIPC.java:
package project;
import java.net.Socket;
import java.net.ServerSocket;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.PrintWriter;
import java.io.OutputStreamWriter;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
public class SocketIPC {
public PrintWriter out;
public BufferedReader in;
Socket socket = null;
ServerSocket serverSocket = null;
ConnectionListener connlisten = null;
DataListener datalisten = null;
Thread connlisten_thread = null;
Thread datalisten_thread = null;
CommandObject ipc_event_cmd = null;
// Server thread accepts incoming client connections
class ConnectionListener extends Thread {
private int port;
ConnectionListener(int port) {
this.port = port;
}
@Override
public void run() {
try {
serverSocket = new ServerSocket(port);
socket = serverSocket.accept();
out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
datalisten = new DataListener();
datalisten_thread = new Thread(datalisten);
datalisten_thread.start();
} catch (Exception e) {
System.err.println("SocketIPC creation error: " + e.getMessage());
}
}
}
// Server thread accepts incoming client connections
class DataListener extends Thread {
String data_str = null;
DataListener() {
}
@Override
public void run() {
try {
while(true) {
data_str = recv();
ipc_event_cmd.buffer.add(data_str);
ipc_event_cmd.execute();
}
} catch (Exception e) {
System.err.println("SocketIPC reading error: " + e.getMessage());
}
}
public String read() {
String ret_string = null;
if(!ipc_event_cmd.buffer.isEmpty()) {
ret_string = ipc_event_cmd.buffer.remove(0);
}
return ret_string;
}
}
public SocketIPC(int port) {
ipc_event_cmd = new CommandObject();
connlisten = new ConnectionListener(port);
connlisten_thread = new Thread(connlisten);
connlisten_thread.start();
}
public void send(String msg) {
if (out != null) {
out.println(msg);
}
}
public void flush() {
if (out != null) {
out.flush();
}
}
public void close() {
if (out != null) {
out.flush();
out.close();
try {
in.close();
socket.close();
serverSocket.close();
} catch (Exception e) {
System.err.println("SocketIPC closing error: " + e.getMessage());
}
}
}
public String recv() throws Exception {
if (in != null) {
return in.readLine();
} else {
return "";
}
}
public void set_cmd(CommandObject event_cmd) {
if (event_cmd != null) {
this.ipc_event_cmd = event_cmd;
}
}
}
CommandObject.java:
package project;
import java.util.List;
import java.util.ArrayList;
public class CommandObject {
List<String> buffer;
public CommandObject() {
this.buffer = new ArrayList<String>();
}
public void execute() {
}
}
DoStuff.java:
package project;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;
import java.util.Random;
public class DoStuff extends CommandObject {
public DoStuff () {
}
@Override
public void execute() {
String tmp_string = null;
while (!buffer.isEmpty()) {
tmp_string = buffer.remove(0);
// Do Stuff
}
}
}
答案 1 :(得分:1)
听起来像Jython的工作! Jython是一个用Java编写的可嵌入Python运行时。只要您不需要在另一个进程中运行Python脚本(例如,希望能够杀死它,可能使用大量内存等),这是迄今为止最好的方法。
答案 2 :(得分:1)
如果您正在尝试将Java和python一起工作,那么请使用Jython简化您的生活。
JPython的继任者Jython是Python的一个实现 用Java编写的编程语言。 Jython程序可以导入和 使用任何Java类。除了一些标准模块,Jython程序 使用Java类而不是Python模块。 Jython几乎包括所有 标准Python编程语言中的模块 分发,缺少最初实现的一些模块 在C.
假设你的python路径中有java lib。这是一个代码片段,让您了解使用java类是多么简单:
'''
Import JavaUtilities class from a java package
'''
from com.test.javalib import JavaUtilities
'''
Call a java method
'''
response = JavaUtilities.doSomething();
答案 3 :(得分:0)
请查看Jython,这最适合java和Python之间的通信。