使用Java ProcessBuilder与SQLite shell进行交互

时间:2014-01-23 21:09:39

标签: java sqlite processbuilder

我使用以下两种方法手动运行sqlite3.exe。

  1. 如果我在Windows命令行输入'sqlite3.exe test.db',sqlite3会进入其交互式shell,我可以输入各种命令。

  2. 如果我输入第三个SQL参数,例如。 'SQLite.exe test.db“SELECT * FROM clients”',sqlite3不以交互方式运行,但请求的数据通过stdout输出。

  3. 我想从java代码(第一个场景)中与shell中的提示进行交互。

    使用以下快速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确实进入了交互模式,但输入流不是由shell的stdout提供的。我希望看到交互式提示文本,并能够将命令写入输出流。

    Java和ProcessBuilder有可能吗?

    感谢。

1 个答案:

答案 0 :(得分:2)

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

  

默认情况下,创建的子进程没有自己的终端或控制台。它的所有标准I / O(即stdin,stdout,stderr)操作将被重定向到父进程,在那里可以通过使用方法getOutputStream(),getInputStream()和getErrorStream()获得的流来访问它们。父进程使用这些流向子进程提供输入并从子进程获取输出。

您可以从Process获取OutputStream,并在交互式运行SqlLite时将其直接写入控制台中,然后将其写入。

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

然后像你一样读取InputStream,它应该具有你在交互运行SqlLite时通常会看到的输出。