我需要执行一个bat文件,该文件在Windows 10和Java-8中使用psql.exe在命令行中执行PostgreSQL查询。我必须通过bat文件执行查询,仅用于测试bat文件。下面是蝙蝠文件的内容
postgresql\bin\psql.exe -U username -p dbport -h 127.0.0.1 -c "
insert into table1 values(value1,value2);
insert into table2 values(value1,value2);
insert into table3 values(value1,value2) database"
我尝试使用java ProcessBuilder调用bat文件,但是pgsql要求输入密码。下面是我用来调用bat文件并提供密码的代码,但是它无法正常工作。
主类:
import java.io.BufferedWriter;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.util.Scanner;
public class ProcessTest {
public static void main(String args[])
{
Process process=null;
String batFile="\"c:\\batfilepath\\test.bat\"";
ProcessBuilder processBuilder=new ProcessBuilder(batFile);
try {
//process=Runtime.getRuntime().exec(batFile);
process=processBuilder.start();
StreamEater inputStreamEater=new StreamEater(process.getInputStream());
StreamEater errorStreamEater=new StreamEater(process.getErrorStream());
inputStreamEater.start();
errorStreamEater.start();
BufferedWriter writer=new BufferedWriter(new OutputStreamWriter(process.getOutputStream()));
writer.write("password");
writer.newLine();
writer.close();
int errorcode=process.waitFor();
System.out.println("errorcode:"+errorcode);
}
catch(Exception exception)
{
exception.printStackTrace();
}
}
}
StreamEater类
class StreamEater extends Thread
{
private InputStream inputStream=null;
public StreamEater(InputStream stream)
{
this.inputStream=stream;
}
public void run()
{
System.out.println("Stream Eater thread started");
Scanner scanner=new Scanner(new InputStreamReader(inputStream));
String message="";
StringBuilder sb=new StringBuilder("");
try
{
System.out.println("before reading message");
while(scanner.hasNextLine())
{
message=scanner.nextLine();
sb.append(message);
sb.append("\n");
}
scanner.close();
System.out.println("after reading message "+sb.toString());
}
catch(Exception exception)
{
exception.printStackTrace();
}
System.out.println("Stream Eater thread ended");
}
}
有人能指出我犯了什么错误吗?还有其他方法可以将输入发送到bat文件吗?
答案 0 :(得分:2)
此代码存在多个问题。我将首先回答您的直接问题。
传递密码参数(直接回答)
pgsql command强制用户以交互方式输入密码。 This SO answer describes two techniques to handle this:
processBuilder.environment().put("PGPASSWORD ", "PASSWORD");
使用JDBC(改进代码)
使用JDBC,而不是让Java应用程序调用批处理文件。 JDBC确实存在,因此Java可以连接到数据库并针对该数据库运行查询。
这将避免调用批处理脚本的麻烦,并使您的应用程序直接与数据库进行交互。
答案 1 :(得分:0)
我认为您的线程将很快结束,因为扫描程序没有要读取的行。虽然它可能被阻止,但是您应该循环该线程。上面的答案也很好,但是请尝试这样做,而不会对您的代码造成太大影响:
while (stillReading) {
while(scanner.hasNextLine())
{
message=scanner.nextLine();
sb.append(message);
sb.append("\n");
}
Thread.sleep(1000);
}
主要问题是线程启动时InputStream中没有输入。