2016-06-14 2 views
1

Java 파일에서 하이브 쿼리를 실행하려고합니다. 쇼 데이터베이스 쿼리에서 마지막 결과 만 얻고 싶습니다.결과의 마지막 값을 효율적으로 가져 오는 방법

모든 쿼리 결과를 반복하여 마지막 값을 찾는 대신 마지막 출력을 직접 가리키는 방법이 있습니까? 내가 그것을보고, 단지 스트림 프로세스가 (일부 Java 인터페이스 API가없는 않는, 그래서, 스트림의 아이디어가 순차 액세스입니다 https://docs.oracle.com/javase/8/docs/api/java/lang/Process.html

를 참조 Process 클래스에서 지원하는

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

오라클 데이터베이스 접근을위한 OJDBC와 같이) 마지막 줄에 올 때까지 스트림을 통해서만 반복 할 수 있습니다. 미안합니다.

+0

하이브 쿼리를 실행할 수있는 다른 방법이 있습니까? 하이브 연결을 사용하는 것 외에도 – Ninja

+0

나는 잘 모르겠다. – GreenThor

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 (...) { 
      ... 
     } 
    } 
관련 문제