我正在尝试从java文件执行配置单元查询。我想只获取show database查询的最后一个结果。
有没有办法直接指向最后一个输出,而不是遍历所有查询结果以找出最后一个值。
example : show databases ;
Db1
DB2
DB3
Output should be DB3
public class Test {
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
ProcessBuilder hiveProcessBuilder = new ProcessBuilder("hive", "-e",
"show databases");
Process hiveProcess = hiveProcessBuilder.start();
OutputRedirector outRedirect = new OutputRedirector(
hiveProcess.getInputStream(), "HIVE_OUTPUT");
OutputRedirector outToConsole = new OutputRedirector(
hiveProcess.getErrorStream(), "HIVE_LOG");
outRedirect.start();
outToConsole.start();
}
public static class OutputRedirector extends Thread {
InputStream is;
String type;
public OutputRedirector(InputStream is, String type) {
this.is = is;
this.type = type;
}
@Override
public void run() {
try {
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line = null;
while ((line = br.readLine()) != null) {
String result = line;
System.out.println(type + "> " + result);
}
} catch (IOException ioE) {
}
}
}
}
答案 0 :(得分:1)
一般来说,您通常会在输入流中解析并等待所需的内容。
但是,当您尝试捕获命令行程序的输出时,您还不知道它何时完成。因此,我不会使用BufferedReader,而是使用InputStreamReader本身定期读取字符。你可以通过读取每秒钟的几个字符来做到这一点,并记住最后一个换行符以了解你的整行。
最后,您应该检查一个指示符,该指示符显示您已到达结果集的末尾。
此外,此线程将永远运行,因此如果您不再需要它,但您不想关闭父进程(例如应用程序本身),则必须使用中断来关闭正确处理,您可以在此处查看如何操作:http://docs.oracle.com/javase/7/docs/technotes/guides/concurrency/threadPrimitiveDeprecation.html
@Override
public void run() {
try {
InputStreamReader in = new InputStreamReader(is);
StringBuilder buffer = new StringBuilder();
String currentLastLine = null;
while (true) {
int nextchar = in.read();
//nextchar == -1 -> we are at the end of the stream
if (nextchar == -1) {
Thread.sleep(1000);
} else {
buffer.append(nextchar);
}
//new line here
if (nextchar == 10) {
// check for end of result indicator
String newLastLine = buffer.toString();
// this could be something like .contains('hive >') as well
// END_OF_RESULT_SET must be defined according to your output
if (newLastLine.matches(END_OF_RESULT_SET)) {
// here currentLastLine is your desired line,
// so do something with it
System.out.println("Result: "+currentLastLine);
}
currentLastLine = newLastLine;
buffer = new StringBuilder();
}
}
} catch (IOException ioE) {
...
} catch (...) {
...
}
}
答案 1 :(得分:0)
正如我所看到的,Process类只支持流,请参阅 https://docs.oracle.com/javase/8/docs/api/java/lang/Process.html
流的概念是顺序访问,所以除非你的进程没有一些Java接口API(比如用于访问Oracle数据库的OJDBC),否则你只能遍历你的流,直到你到达最后一行,我对不起。