如何从java调用python脚本并返回长文本?

时间:2015-07-27 09:13:19

标签: java python

我需要从Java应用程序调用python脚本并返回大文本(json响应)。我成功调用了脚本,我可以将一些文本返回给Java应用程序。但是,当我尝试返回完整的json响应时 - 我的Java应用程序冻结,没有任何事情发生。 我如何调用python脚本:

ProcessBuilder pb = new ProcessBuilder(
    "python", absolutePath, params
);
Process ps = pb.start();

BufferedReader reader = new BufferedReader(
    new InputStreamReader(ps.getInputStream())
);

ps.waitFor();
int ec = ps.exitValue();
StringBuffer HTTPResponse = new StringBuffer();
String inputLine;

while ((inputLine = reader.readLine()) != null) {
        logger.debug(String.format("DEBUG!!!: input = %s", inputLine));
        HTTPResponse.append(inputLine);
}

1 个答案:

答案 0 :(得分:0)

您正在遇到父进程和子进程之间的死锁。

这是因为您的java应用程序在终止之前不会从子进程读取任何内容。 Python将缓冲它的输出(在我的系统上高达64k),一旦缓冲区填满,它将在下一次写入时阻塞。因为它被阻止,它不会终止。同时java父母也被阻止等待孩子终止,这自然不会发生。

要解决这个问题,你需要重构你的Java代码,而不是等待孩子在处理它的输出之前终止它,从孩子那里读取,直到孩子终止,如下所示:

import java.io.*;

public class TestProcess {
    public static void main(String[] args)
        throws InterruptedException, IOException
    {
       ProcessBuilder pb = new ProcessBuilder(
           "python", absolutePath, params
       );
       Process ps = pb.start();

       BufferedReader reader = new BufferedReader(
           new InputStreamReader(ps.getInputStream())
       );

       String inputLine;
       while ((inputLine = reader.readLine()) != null) {
               System.out.println(inputLine);
       }

       ps.waitFor();
       int ec = ps.exitValue();
       System.out.println("Child returned " + ec);
   }
}

你的Python脚本可能是:

print 'a' * (1024*1024)

将产生1MiB的数据。