2016-09-21 91 views
2
等待输入

我有以下短Python程序“test.py”的Runtime.exec()在Java挂起因为它是从System.in

n = int(raw_input()) 
print n 

我是从下面的Java执行上述程序节目 “ProcessRunner.java”

import java.util.*; 
import java.io.*; 

public class ProcessRunner { 
    public static void main(String[] args) { 
     try { 
      Scanner s = new Scanner(Runtime.getRuntime().exec("python test.py").getInputStream()).useDelimiter("\\A"); 
      System.out.println(s.next()); 
     } 

     catch(Exception e) { 
      System.out.println(e.getMessage()); 
     } 
    } 
} 

在运行命令,

java ProcessRunner 

我不能够通过在亲值 'N'每种格式的Python程序和Java运行挂起。什么是正确的方式来处理这种情况,并从java程序中动态地将值'n'传递给python程序?

+0

看看这里http://stackoverflow.com/questions/18903549/writing-to-inputstream-of-a-java-process关于如何与Python进程进行通信的信息。 –

+0

另请参阅[当Runtime.exec()不会](http://www.javaworld.com/article/2071275/core-java/when-runtime-exec---won-t.html)很多很好的有关正确创建和处理过程的提示。然后忽略它是指'exec'并使用'ProcessBuilder'来创建进程。还要将'String arg'分解为'String [] args'来解释包含空格字符的路径。 –

回答

1

raw_input()input()在Python 3中将阻止在标准输入上等待新的行终止输入,但是Java程序没有发送任何东西。

尝试使用由getOutputStream()返回的流写入Python子流程。下面是一个例子:

import java.util.*; 
import java.io.*; 

public class ProcessRunner { 
    public static void main(String[] args) { 
     try { 
      Process p = Runtime.getRuntime().exec("python test.py"); 
      Scanner s = new Scanner(p.getInputStream()); 
      PrintWriter toChild = new PrintWriter(p.getOutputStream()); 

      toChild.println("1234"); // write to child's stdin 
      toChild.close();   // or you can use toChild.flush() 
      System.out.println(s.next()); 
     } 

     catch(Exception e) { 
      System.out.println(e.getMessage()); 
     } 
    } 
} 

另一种方法是通过n作为命令行参数。这需要Python脚本的修改期望和处理命令行参数,以及Java代码发送说法:

import java.util.*; 
import java.io.*; 

public class ProcessRunner { 
    public static void main(String[] args) { 
     try { 
      int n = 1234; 
      Process p = Runtime.getRuntime().exec("python test.py " + n); 
      Scanner s = new Scanner(p.getInputStream()); 
      System.out.println(s.next()); 
     } 

     catch(Exception e) { 
      System.out.println(e.getMessage()); 
     } 
    } 
} 

而Python脚本,test.py

import sys 

if len(sys.argv) > 1: 
    print int(sys.argv[1]) 
+0

完美!这就是我一直在寻找:) – saint1729

+0

如果外部程序是一个java程序而不是python程序,那么即使遵循上述相同的程序,它也会挂起。 – saint1729

0

如果我没有理解你正确地想让你的java程序将你的python脚本的任何输出传递给System.out,并把你的java程序中的任何输入传递给你的python脚本,对吗?

看看下面的程序来了解你如何做到这一点。

import java.io.IOException; 
import java.io.InputStream; 
import java.io.OutputStream; 

public class ProcessRunner { 

    public static void main(String[] args) { 
     try { 
      final Process process = Runtime.getRuntime().exec("/bin/sh"); 

      try (
        final InputStream inputStream = process.getInputStream(); 
        final InputStream errorStream = process.getErrorStream(); 
        final OutputStream outputStream = process.getOutputStream() 
      ) { 

       while (process.isAlive()) { 
        forwardOneByte(inputStream, System.out); 
        forwardOneByte(errorStream, System.err); 
        forwardOneByte(System.in, outputStream); 
       } 
      } 
     } catch (IOException e) { 
      throw new RuntimeException(e); 
     } 
    } 

    private static void forwardOneByte(final InputStream inputStream, 
             final OutputStream outputStream) 
    throws IOException { 
     if(inputStream.available() <= 0) { 
      return; 
     } 

     final int b = inputStream.read(); 
     if(b != -1) { 
      outputStream.write(b); 
      outputStream.flush(); 
     } 
    } 
} 

注意此代码只是一个概念演示。它会吃掉你的CPU,并且不能应付更大的吞吐量。