【问题标题】:calling a perl script from a java code in a interactive way以交互方式从 java 代码调用 perl 脚本
【发布时间】:2011-10-03 00:41:07
【问题描述】:

有人可以在以下情况下帮助我吗,

我需要从我的 java 代码中调用 perl 脚本。 perl 脚本是一个交互式代码,它在执行过程中从用户那里获取输入并继续到结束。因此,我使用的示例是,执行时的 perl 脚本通过在控制台中打印“你多大了?”来询问年龄,当用户输入一些值说“26”时。然后它会打印“哇!你已经 26 岁了!”。

当我尝试从我的 java 代码中调用此脚本时,该过程一直等到我在输出流中将值设为 26,而在输入流中没有值。最后,当我再次阅读输入流时,我将脚本的整个输出放在一起。那么,我不能让它互动吗?

我浏览了许多论坛和博客,但找不到任何符合我要求的论坛和博客。

这里是java代码

import java.io.*;

public class InvokePerlScript {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Process process;

        try
        {
        process = Runtime.getRuntime().exec("cmd /c perl D:\\sudarsan\\eclips~1\\FirstProject\\Command.pl");

              try {
            BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String line = null;
            while ((line = in.readLine()) != null) {
                System.out.println(line);
             }
                } catch (IOException e) {
          e.printStackTrace();
                 }

        try {
            BufferedWriter out = new BufferedWriter(new OutputStreamWriter(process.getOutputStream()));
            out.write("23");
            out.flush();
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

            process.waitFor();
        if(process.exitValue() == 0)
        {
        System.out.println("Command Successful");
            try {
                BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
                String line = null;
                while ((line = in.readLine()) != null) {
                System.out.println(line);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        else
        {
        System.out.println("Command Failure");
            try {
                BufferedReader in = new BufferedReader(new InputStreamReader(process.getErrorStream()));
                String line = null;
                while ((line = in.readLine()) != null) {
                System.out.println(line);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        }
        catch(Exception e)
        {
        System.out.println("Exception: "+ e.toString());
        }
    }

}

Perl 代码如下

$| = 1;
print "How old are you? \n";
$age = <>;
print "WOW! You are $age years old!";

提前致谢, 苏达山

【问题讨论】:

  • 请发布您正在使用的 java 和 perl 代码。
  • 听起来你有缓冲问题。您是否尝试在 perl 中将 $| 设置为非零以刷新输出?
  • 在添加 $|=1 之后这也不起作用:-(

标签: java perl integration


【解决方案1】:

写入值后,您是否在 Java 中的 OutputStream 上调用 flush()?如果你不这样做,它们很可能会被保存在 Java 进程中的流缓冲区中,因此永远不会进入 Perl(结果两个进程最终都在等待对方的 IO。)

(取决于流的实现,这可能是必要的,也可能不是必要的,但它肯定不会受到伤害 - 我过去一直被这个咬伤。通常不需要那么小心,因为在调用close() 时会隐式进行刷新,但在这里你不能在完成写入后关闭流。)

【讨论】:

  • 嗨 Adrzej,我的问题不在于 outputStream。我想读取输入流中的数据(perl 代码中的第一个打印语句),然后将我的数据刷新回 outputStream,最后通过再次读取输入流获得 perl 代码的第二个打印语句。
【解决方案2】:

您似乎正在尝试阅读此代码中的完整行:

        BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
        String line = null;
        while ((line = in.readLine()) != null) {
           ...

但是,在您的 perl 代码中,您没有打印结束行字符,因此 readLine 永远不会返回(根据 documentation)。

【讨论】:

  • 哇,这真是一个很好的收获。谢谢你,这是有道理的。现在我已经修改了 perl 代码以具有结束行字符和 java 代码来读取 perl 脚本的第一输出行。现在我在我的 java 控制台中得到了第一个打印语句,但是 java 代码没有继续进行,当我调试时,我发现主线程一直在 "line = in.readLine()" 行等待。请建议如何摆脱这个,我不能在阅读我的第一行后立即使用 in.close(),因为在我想阅读之后可能会有更多的行。
  • @sudan,你需要在while循环中添加逻辑来处理perl脚本的输出,否则你必须做一些线程,一个线程监听输出,一个线程将输入汇集到 perl。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-10
  • 1970-01-01
  • 1970-01-01
  • 2012-06-15
相关资源
最近更新 更多