Java - 运行Python脚本并监视连续输出

时间:2016-03-21 22:45:54

标签: java python raspberry-pi processbuilder spi

我正在使用Raspberry Pi从RC522阅读器接收某些RFID卡的UID。我正在运行的python脚本在这里:https://github.com/mxgxw/MFRC522-python

由于各种原因我不打算进入,我必须用Java处理这些ID。

似乎最可行的解决方案是运行python脚本并将结果读入Java。问题是,Python代码提供连续输出,它将卡片的ID打印到控制台窗口中,当卡片被轻敲到阅读器上时,只会在用户的命令中终止。

我目前正在使用ProcessBuilder来执行脚本,但是它似乎更适合运行程序并将直接结果读回Java(当然,如果我是 null 没有在读卡器上敲卡。)我尝试在while(true)循环中执行代码以不断启动进程 - 但这不起作用:

    import java.io.*;

public class PythonCaller {

    /**
     * @param args
     * @throws IOException
     */
    public static void main(String[] args) throws IOException {
        // set up the command and parameter
        String pythonScriptPath = "/home/pi/MFRC522-python/Read.py";
        String[] cmd = new String[3];
        cmd[0] = "sudo";
        cmd[1] = "python"; // check version of installed python: python -V
        cmd[2] = pythonScriptPath;

        // create runtime to execute external command
        ProcessBuilder pb = new ProcessBuilder(cmd);

        // retrieve output from python script
        pb.redirectError();

        while(true){
            Process p = pb.start();
            System.out.println("Process Started...");
            BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
            int ret = new Integer(in.readLine()).intValue();
            System.out.println("value is : "+ret);
            }
        }
}

控制台窗口上的输出为空白 - 没有抛出异常或println。

任何帮助都会受到大力赞赏!!

由于

编辑 - 我在try / catch中包围了我的代码,看看是否有任何东西被抛出,而且似乎并非如此

2 个答案:

答案 0 :(得分:1)

我使用以下程序尝试重现问题

<强> PythonCaller.java

import java.io.*;    
public class PythonCaller {

    public static void main(String[] args) throws IOException {
        // set up the command and parameter
        String pythonScriptPath = "/home/pi/test.py";
        String[] cmd = { "python", pythonScriptPath };

        // create runtime to execute external command
        ProcessBuilder pb = new ProcessBuilder(cmd);

        // retrieve output from python script       
        pb.redirectError();

        while(true){
            Process p = pb.start();
            System.out.println("Process Started...");
            BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
            int ret = new Integer(in.readLine()).intValue();
            System.out.println("value is : "+ret);
        }
    }
}

<强> test.py

uid =(123,456,789,999)
print "Card read UID: "+str(uid[0])+","+str(uid[1])+","+str(uid[2])+","+str(uid[3])
  1. 方法pb.redirectError()不会修改任何内容。它返回一个值,你的代码对它没有任何作用。 (见http://docs.oracle.com/javase/7/docs/api/java/lang/ProcessBuilder.html#redirectError%28%29)。您想要的可能是redirectErrorStream(boolean redirectErrorStream)

  2. python测试程序的第二行直接取自&#34; Read.py&#34; (第44行)。它会导致java intValue()方法出错。如果我用String ret = in.readLine();替换它,该程序似乎有效。

  3. 由于Process p = pb.start();位于循环内部,因此会重复调用python子程序。

  4. 下一步应该是尝试在控制台中手动运行python程序,看看它做了什么。

    (n.b。我必须删除&#34; sudo&#34;并更改路径以便能够在我的系统上进行测试,您应该没有问题替换您的设置)。

答案 1 :(得分:0)

我设法通过编辑我的Python脚本来解决它 - 如果读卡器上没有卡,则返回null,如果有,则返回UID。

我可能会在Java端使用观察者模式或类似物来检测何时出现卡片。资源非常密集,但现在必须要做!