Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/redis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
需要通过java进程执行postgresql查询的帮助吗_Java - Fatal编程技术网

需要通过java进程执行postgresql查询的帮助吗

需要通过java进程执行postgresql查询的帮助吗,java,Java,我需要在windows 10和Java-8中使用psql.exe在命令行中执行PostgreSQL查询的bat文件。我必须通过bat文件执行查询,仅用于测试bat文件。下面是bat文件的内容 BatFileContents: 我尝试使用java ProcessBuilder调用bat文件,但pgsql要求输入密码。下面是我用来调用bat文件并提供密码的代码,但它没有按预期工作 代码: 主要类别: import java.io.BufferedWriter; import java.io.File

我需要在windows 10和Java-8中使用psql.exe在命令行中执行PostgreSQL查询的bat文件。我必须通过bat文件执行查询,仅用于测试bat文件。下面是bat文件的内容

BatFileContents: 我尝试使用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();
        }

    }


}
拖缆级

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文件发送输入。

此代码有几个问题。我会先回答你的直接问题

传递密码参数(直接回答)

强制用户以交互方式输入密码

  • 使用.pgpass文件。您可以独立于程序创建此文件,并更改BAT文件以引用它
  • 设定一个目标。您可以更改BAT文件来执行此操作。使用类似于
    processBuilder.environment()的代码put(“PGPASSWORD”、“PASSWORD”)
  • 使用JDBC(改进代码)

    不要让Java应用程序调用批处理文件,而是使用。JDBC确实存在,因此Java可以连接到数据库并对该数据库运行查询


    这将避免调用批处理脚本的挑战,并让您的应用程序直接与数据库交互。

    我认为您的线程将很快结束,因为扫描仪没有行可读取。虽然它可能会被阻塞,但您应该循环此线程。上面的答案也很好,但请在不太影响代码的情况下进行尝试:

    while (stillReading) {
        while(scanner.hasNextLine())
             {
               message=scanner.nextLine();
               sb.append(message);
               sb.append("\n");
    
             }
    Thread.sleep(1000);
    }
    

    主要问题是线程启动时InputStream中没有输入。

    不清楚为什么不使用jdbc。bat文件需要在我正在使用的工具中没有java的情况下单独测试。因此我在这里没有使用jdbc。所有这些都有,只缺少2行代码。如果你愿意,我可以做,但仔细看看有什么遗漏。您的代码很好,只是在通过流传递密码时存在安全风险。@MS90-如果您有解决方案,请发布答案。基于编辑和其他评论,OP似乎致力于此方法,而不考虑其他解决方案或安全问题。但我不允许更改bat文件。关于传递密码参数的解释非常好,我不太清楚为什么人们会赤裸裸地编写代码。@tazz请看我的编辑。我希望这能直接回答你的问题。如果您在ProcessBuilder中设置PGPASSWORD,那么启动BAT它应该可以工作。您的意思是像ProcessBuilder.environment()一样添加它。put(“PGPASSWORD”、“PASSWORD”);对,我在环境映射中添加了这一点,但仍然是相同的代码。是否可以只传递输入密码。我不需要命令的输出。因此,如果我删除inputstream读取,它将工作。
    while (stillReading) {
        while(scanner.hasNextLine())
             {
               message=scanner.nextLine();
               sb.append(message);
               sb.append("\n");
    
             }
    Thread.sleep(1000);
    }