当前位置: 动力学知识库 > 问答 > 编程问答 >

java - Redirecting program output as input - pipe not working

问题描述:

I am taking the output of one program (C++) as input for another (Java) using BufferedReader. When I run the Java program in my IDE and enter input in the console the program works as expected, however, when I try to pipe the input from the C++ program it no longer works with no errors given - no output is shown on the terminal window and no data is entered into the database. It is also worth noting that if I try running the jar in a terminal window and entering input the program does not work there either.

Reader Code:

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);

}

I am using the Linux terminals pipe function to pass the information across.

Command:

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

EDIT:

For sake of thoroughness I've included the output code from the C++ program, would the method I'm using to print the timestamp be causing problems?

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;

}

}

As asked in comments, this is an example of the C++ output (from the line Aug 17.... to opengl support available are only printed at program start and are not printed again.

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

Also if I comment out the line beginning to the end of the scope:

String regEx...

...

}

The Java program outputs as expected to the terminal but I've had to comment out the database upload to test this so I cannot verify if the upload works.

网友答案:

My guess would be that the your program is blocked in something unrelated to the pipe. Most likely the database. The IDE could be setting a classpath and/or VM options that differ from what you enter at the terminal.

Get the exact command line being run by the IDE, if you don't know how to do this with your IDE you can do it with jps and /proc//cmdline.

eg. if I run jps while I am running my program in the IDE, I see:

13923 Jps 11333 MyJFrame 15006 Main

I know my main class is MyJFrame so I know my PID must be 11333.

If I run cat /proc/11333/cmdline, I get:

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

It is missing the spaces between arguments but it is fairly obvious where they would go. Run that command after carefully inserting the spaces on the terminal.

Also, it would be a good idea to see exactly which line is executing when you run the jar and it produces no output. Run the original command, use jps to get the pid, use jstack on that pid to get all the stack frames including the line it is blocked on.

网友答案:

I ended up fixing this by removing the defauls jar configuration and re-adding it, instructions below for anyone else using IntelliJ IDEA.

File -> Project Structure -> Artifacts

Then remove the jar settings using the small minus button and re-add using the plus symbol.

JAR -> From modules with dependencies -> OK
分享给朋友:
您可能感兴趣的文章:
随机阅读: