2014-01-23 1 views
2

다음 두 가지 방법을 사용하여 sqlite3.exe를 수동으로 실행합니다. 나는 Windows 명령 줄에서 'sqlite3.exe의 test.db'를 입력하면Java ProcessBuilder를 사용하여 SQLite 셸과 상호 작용

  1. 는 sqlite3를 내가 여러 가지 명령을 입력 할 수있는 대화 형 쉘을 입력합니다.

  2. 대신에 세 번째 SQL 인수를 입력하십시오. 'SQLite.exe test.db "SELECT * FROM clients"', sqlite3은 대화 형으로 실행되지 않지만 요청 된 데이터는 stdout을 통해 출력됩니다.

Java 코드 (첫 번째 시나리오)에서 셸의 프롬프트와 상호 작용하고 싶습니다.

다음 빠른 Java 코드를 사용하여 SQLite3.exe를 비 대화식으로 실행할 수 있습니다 (두 번째 시나리오).

char[] readBuffer=new char[1000]; 

    //Third parameter in constructor is the select statement 
    ProcessBuilder pBuilder=new ProcessBuilder(pathToSQLite3exe, "test.db", 
    "\"SELECT * FROM clients"\"); 

    pBuilder.directory(new File(pathToExeFolder)); 
    pBuilder.redirectErrorStream(true); 

    Process process=pBuilder.start(); 

    InputStreamReader reader=new InputStreamReader(process.getInputStream()); 

    int charCount; 

    while (true) 
    { 
     charCount=reader.read(readBuffer); 
     if (charCount>0) 
     { 
      System.out.print(new String(readBuffer,0,charCount)); 
     } 
     else 
     { 
      break; 
     } 
    } 

예상대로 위의 작품, 나는 ProcessBuilder를 생성자에서 세 번째 매개 변수 (select 문)을 생략하는 경우에는 문자가 없기 때문에하지만, 프로그램이 아마도 reader.read() 문에서 영원히 일시 정지 독서. sqlite3.exe 실제로 대화 형 모드를 입력 한 있지만 입력 스트림을 셸 stdout에 의해 공급되지 않는 것이 겠지요. 대화식 프롬프트 텍스트를보고 출력 스트림에 명령을 쓸 수 있기를 바랬습니다.

Java 및 ProcessBuilder에서 가능합니까?

감사합니다. Process의 javadoc에서

답변

2

: http://docs.oracle.com/javase/7/docs/api/java/lang/Process.html

기본적으로 작성된 서브 프로세스는 자신의 단말 또는 콘솔이 없습니다. 모든 표준 I/O (즉 stdin, stdout, stderr) 작업은 부모 프로세스로 리디렉션되며 getOutputStream(), getInputStream() 및 getErrorStream() 메서드를 사용하여 가져온 스트림을 통해 액세스 할 수 있습니다. 부모 프로세스는 이러한 스트림을 사용하여 하위 프로세스에 입력을 제공하고 하위 프로세스에서 출력을 가져옵니다.

대화 형으로 SqlLite를 실행할 때 콘솔에서 직접 입력하는 것과 같이 OutputStream을 프로세스에서 가져 와서 쓸 수 있습니다.

OutputStream os = process.getOutputStream(); 
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os)); 
bw.write("SELECT * FROM clients;"); 
bw.newLine(); 
bw.flush(); 

그런 다음 이미했던 것처럼 InputStream을 읽으면 대화 형으로 SqlLite를 실행할 때 일반적으로 볼 수있는 출력이 있어야합니다.

+0

고마워요! 귀하의 제안에 따라 쿼리 결과를 얻었지만 출력은 쉘을 수동으로 실행할 때처럼 SQLite> 프롬프트로 종료되지 않습니다. 그렇다면 입력 스트림에서 모든 데이터를 읽은 시점을 어떻게 결정합니까? 하나의 가능한 해결 방법을 생각 ... 알려진 된 고유 값 (물결표) 반환하는 다른 SELECT 문을 추가하여 데이터의 끝을 표시합니다. 더 좋은 방법이 있습니까? 젠장, 나는 당신의 대답에 투표하는 데 충분한 명성이 없습니다. – EternalIdiot

+0

가장 좋은 방법은 무엇인지 모르겠습니다. 네가하고있는 일이 조금 해킹 되더라도 나는 그것에 충실한다고 말하고 싶다. –