在为子流程运行创建管理器时遇到一些问题。这些子进程就是python脚本。我需要在不同的线程中编写/读取/包装进程的错误。我创建了一些简单的测试:
test.py
import sys
if __name__ == "__main__":
print ("START TEST SCRIPT")
print ("SOME STRING")
for line in sys.stdin:
print ("DEBUG>>> "+ line)
创建一个simpe java测试类:
public class Test {
public static void main(String[] args) {
ProcessBuilder builder = new ProcessBuilder("python", "test.py");
builder.environment().put("PYTHONIOENCODING", "UTF-8");
builder.directory(new File("./test/external_processes/python"));
try {
Process environmentProcess = builder.start();
InputStream out = environmentProcess.getInputStream();
InputStream err = environmentProcess.getErrorStream();
OutputStream in = environmentProcess.getOutputStream();
Thread t1 = new Thread(() -> {
OutputStreamWriter writer = new OutputStreamWriter(in);
try {
writer.write("new string");
writer.flush();
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
});
Thread t2 = new Thread(() -> {
byte[] buffer = new byte[4096];
int count;
try {
while ((count = out.read(buffer)) >= 0) {
System.out.println("[TASK STREAMER] " + new String(buffer, 0, count));
}
out.close();
} catch (IOException e) {
e.printStackTrace();
}
});
Thread t3 = new Thread(() -> {
byte[] rbuffer = new byte[4096];
int rcount;
try {
int rno = err.available();
while ((rcount = err.read(rbuffer)) >= 0) {
System.out.println("[TASK STREAMER ERR] " + rno + " :: " + new String(rbuffer, 0, rcount));
}
err.close();
} catch (IOException e) {
e.printStackTrace();
}
});
t1.start();
t2.start();
t3.start();
t1.join();
t2.join();
t3.join();
environmentProcess.waitFor();
System.out.println("ok!");
environmentProcess.getInputStream().close();
System.exit(0);
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
一切都很顺利
Connected to the target VM, address: '127.0.0.1:50726', transport: 'socket'
[TASK STREAMER] START TEST SCRIPT
SOME STRING
DEBUG>>> new string
Disconnected from the target VM, address: '127.0.0.1:50726', transport: 'socket'
ok!
Process finished with exit code 0
直到我决定不写任何输出,所以我删除了线程t1。在那之后,一个cant从python到达前两行(" START TEST SCRIPT"," START TEST SCRIPT")并且执行被卡住了。
因此,如果代码如下所示:
import java.io.*;
public class Test {
public static void main(String[] args) {
ProcessBuilder builder = new ProcessBuilder("python", "test.py");
builder.environment().put("PYTHONIOENCODING", "UTF-8");
builder.directory(new File("./test/external_processes/python"));
try {
Process environmentProcess = builder.start();
InputStream out = environmentProcess.getInputStream();
InputStream err = environmentProcess.getErrorStream();
Thread t2 = new Thread(() -> {
byte[] buffer = new byte[4096];
int count;
try {
while ((count = out.read(buffer)) >= 0) {
System.out.println("[TASK STREAMER] " + new String(buffer, 0, count));
}
out.close();
} catch (IOException e) {
e.printStackTrace();
}
});
Thread t3 = new Thread(() -> {
byte[] rbuffer = new byte[4096];
int rcount;
try {
int rno = err.available();
while ((rcount = err.read(rbuffer)) >= 0) {
System.out.println("[TASK STREAMER ERR] " + rno + " :: " + new String(rbuffer, 0, rcount));
}
err.close();
} catch (IOException e) {
e.printStackTrace();
}
});
t2.start();
t3.start();
t2.join();
t3.join();
environmentProcess.waitFor();
System.out.println("ok!");
environmentProcess.getInputStream().close();
System.exit(0);
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
我会达到这个目的:
Connected to the target VM, address: '127.0.0.1:50726', transport: 'socket'
我理解这个过程因为python等待输入而不会停止,但我至少期待两个第一个字符串(" START TEST SCRIPT"," START TEST SCRIPT")
但是如果我先关闭输出流,我会达到这个字符串。任何人都可以帮助我理解这种情况,以及如果内部有以太输入读取和写入输出,如何到达子进程输出?
P.S。对不起我的俄语语法。
答案 0 :(得分:0)
在你的python代码中,你需要刷新打印输出。
import sys
if __name__ == "__main__":
print ("START TEST SCRIPT", flush=True)
print ("SOME STRING", flush=True)
for line in sys.stdin:
print ("DEBUG>>> "+ line)
答案 1 :(得分:0)
如果它对任何人都有用,我会在不改变客户端python代码的情况下找到另一种方法。
A已向构建者添加了一些额外的环境:
undefined method create_record for #<ForgotPassword:0x000000000622bc98>