将程序输出重定向为输入 - 管道不工作

时间:2015-08-17 09:50:50

标签: java c++ linux io bufferedreader

我使用BufferedReader将一个程序(C ++)的输出作为另一个程序(Java)的输入。当我在IDE中运行Java程序并在控制台中输入输入时,程序按预期工作,但是,当我尝试从C ++程序管道输入时,它不再有效,没有给出错误 - 终端上没有显示输出窗口,没有数据输入数据库。值得注意的是,如果我尝试在终端窗口中运行jar并输入输入,则该程序也不起作用。

读者代码:

BufferedReader input;
      try {
        input = new BufferedReader(new InputStreamReader(System.in));
        String outputLine;
        String visionObjectName;
        String visionObjectTimestamp;
        String word = null;
        String timestamp = null;
        String whiteSpace = null;
        // Regex is used to check that the output is an object "name blankSpace timestamp" to avoid random output such as errors being entered.
        while ((outputLine = input.readLine()) != null) {
          System.out.println(outputLine);
          String regEx = "(^[a-zA-Z]*)(\\s+)((?:2|1)\\d{3}(?:-|\\/)(?:(?:0[1-9])|(?:1[0-2]))(?:-|\\/)(?:(?:0[1-9])|(?:[1-2][0-9])|(?:3[0-1]))(?:T|\\s)(?:(?:[0-1][0-9])|(?:2[0-3])):(?:[0-5][0-9]):(?:[0-5][0-9]))";
          Pattern p = Pattern.compile(regEx, Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
          Matcher m = p.matcher(outputLine);
          if (m.find()) {
            word = m.group(1);
            whiteSpace = m.group(2);
            timestamp = m.group(3);
          }
          visionObjectName = word + "" + whiteSpace;
          visionObjectTimestamp = timestamp;
          databasePopulation(visionObjectName, visionObjectTimestamp);
        }

我正在使用Linux终端管道功能来传递信息。

命令:

./ORBMarkerDetection | java -jar ../layers/out/artifacts/layers_jar/layers.jar

编辑: 为了彻底,我已经包含了C ++程序的输出代码,我用来打印时间戳的方法会导致问题吗?

int timeFound() {
  time_t rawtime;
  struct tm * timeinfo;
  char buffer [80];
  time(&rawtime);
  timeinfo = localtime (&rawtime);
  strftime(buffer,80,"%Y-%m-%d %H:%M:%S",timeinfo);
  puts(buffer);
  return 0;
}

void printFunction(String objectName) {
  if(nameArray[0] != objectName) {
    nameArray[0] = objectName;
    cout << nameArray[0] << " ";
    timeFound();
    cout << flush;
  }
}

正如评论中所述,这是C ++输出的一个示例(从Aug 17....行到opengl support available仅在程序启动时打印,不会再次打印。

Aug 17, 2015 11:57:03 AM com.layers.Main main
INFO: Logger Created.
Please enter activity number: 
1.1
VIDIOC_QUERYMENU: Invalid argument
VIDIOC_QUERYMENU: Invalid argument
VIDIOC_QUERYMENU: Invalid argument
VIDIOC_QUERYMENU: Invalid argument
VIDIOC_QUERYMENU: Invalid argument
VIDIOC_QUERYMENU: Invalid argument
VIDIOC_QUERYMENU: Invalid argument
VIDIOC_QUERYMENU: Invalid argument
VIDIOC_QUERYMENU: Invalid argument
VIDIOC_QUERYMENU: Invalid argument
VIDIOC_QUERYMENU: Invalid argument
VIDIOC_QUERYMENU: Invalid argument
VIDIOC_QUERYMENU: Invalid argument
VIDIOC_QUERYMENU: Invalid argument
init done 
opengl support available 
tap 2015-08-17 11:57:07
kitchenDoor 2015-08-17 12:57:07
fridge 2015-08-17 13:57:07

此外,如果我将该行开头注释到范围的末尾:

String regEx...
...
}

Java程序按预期输出到终端但我必须注释掉数据库上传以测试这个,所以我无法验证上传是否有效。

2 个答案:

答案 0 :(得分:0)

我的猜测是你的程序被阻塞在与管道无关的东西上。很可能是数据库。 IDE可能正在设置与您在终端输入的类别不同的​​类路径和/或VM选项。

获取IDE运行的确切命令行,如果您不知道如何使用IDE执行此操作,则可以使用jps和/ proc // cmdline执行此操作。

例如。如果我在IDE中运行程序时运行jps,我会看到:

13923 Jps 11333 MyJFrame 15006 Main

我知道我的主要类是MyJFrame,所以我知道我的PID必须是11333。

如果我运行cat / proc / 11333 / cmdline,我会得到:

/usr/local/jdk1.8.0_25/bin/java-Dfile.encoding=UTF-8-classpath/home/shackle/NetBeansProjects/JavaApplication31/build/classesjavaapplication31.MyJFrame

它缺少参数之间的空格,但它们的位置相当明显。小心地在终端上插入空格后运行该命令。

另外,最好在运行jar时确切地看到正在执行的行,并且它不会产生任何输出。运行原始命令,使用jps获取pid,在该pid上使用jstack获取所有堆栈帧,包括它被阻塞的行。

答案 1 :(得分:0)

我最后通过删除默认jar配置并重新添加它来解决这个问题,下面是使用IntelliJ IDEA的其他人的说明。

File -> Project Structure -> Artifacts

然后使用小minus按钮删除jar设置,并使用plus符号重新添加。

JAR -> From modules with dependencies -> OK