java—如何有效地获取结果的最后一个值

6yt4nkrj  于 2021-06-29  发布在  Hive
关注(0)|答案(2)|浏览(264)

我正在尝试从java文件执行配置单元查询。我只想从show数据库查询中获取最后一个结果。
有没有办法直接指向最后一个输出,而不是遍历所有查询结果以找出最后一个值。

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

            }
        }
    }
}
j8yoct9x

j8yoct9x1#

一般来说,您通常会沿着输入流进行解析并等待所需的内容。
尽管如此,当您试图捕获命令行程序的输出时,您仍然不知道它何时完成。因此,我不会使用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 (...) {
          ...
        }
    }
kpbwa7wx

kpbwa7wx2#

在我看来,process类只支持流,请参阅https://docs.oracle.com/javase/8/docs/api/java/lang/process.html
streams的概念是顺序访问,因此除非您的进程没有一些java接口api(比如用于访问oracle数据库的ojdbc),否则您只能在流中迭代,直到到达最后一行,对不起。

相关问题