如何通过“管道”运行 Java ProcessBuilder 到第二个 exe 文件?

问题描述 投票:0回答:1

如果我运行此命令:

raster2pgsql.exe -I -C -s 4326 -t 256x256 -l 4,16 C: aster\sthlm.tif public.斯德哥尔摩 | psql -U postgresuser -d rasterdata -h localhost -p 5432 在windows命令行界面中,命令执行正常。栅格文件导入到 PostgreSQL 数据库“rasterdata”。 但我无法让它与 Java ProcessBuilder 一起使用。在上面的命令中有两个 exe 文件(raster2pgsql.exe 和 psql.exe),我不知道如何使用 2 个 exe 文件定义 ProcessBuilder 的命令。

这两个程序的语法是:

RASTER2PGSQL:

-s 使用 srid 4326

-我创建空间索引

-C 使用标准光栅约束

-t 平铺输出 256x256

sthlm.tif 输入文件

-t 平铺输出 256x256*

public.stockholm 加载到此表中

raster2pgsql -s 4326 -I -C -t 256x256 sthlm.tif public.斯德哥尔摩 > elev.sql

PSQL:

-d 连接到此数据库

-u 数据库用户

-h 主机

-p 端口

-f 连接后读取此文件(来自 raster2pgsql 的 SQL 输出)

psql -u postgres -d rasterdata -h localhost -p 5432 -f elev.sql

我不想单独运行程序(首先将转换后的栅格数据存储在磁盘上(elev.sql),然后将elev.sql中的数据插入数据库中。因此我想像Postgis一样将psql传输到raster2pgsql作为PostGIS举例说明(https://postgis.net/docs/using_raster_dataman.html#RT_Raster_Loader): “使用 UNIX 管道可以一步完成转换和上传: raster2pgsql -s 4326 -I -C -M .tif -F -t 100x100 psql -d gisdb"

这是我使用 raster2pgsql 运行代码时输出的示例 | psql:

插入“public”。“斯德哥尔摩 | psql -u postgresuser -d rasterdata -h localhost 5432”(“rast”)值('01000... 等等..

好像只执行了raster2pgsql 我的代码:

ArrayList<String> cmd = new ArrayList<String>();
cmd.add("raster2pgsql.exe");
cmd.add("-I");
cmd.add("-C");
cmd.add("-s");
cmd.add("4326");
cmd.add("-t");
cmd.add("256x256");
cmd.add("-l");
cmd.add("4,16");
cmd.add(c:\raster\sthlm.tif");
cmd.add("public.stockholm | psql -U postgresuser -d rasterdata -h localhost -p 5432);
ProcessBuilder b = MainDialog.gdalProcess; //pre created
b.command(cmd);
Process p=null;
try {
  p = b.start();
} catch (IOException e) {
  e.printStackTrace();
}
try (InputStream processOutput = p.getInputStream()) {
   BufferedReader bufIn = new BufferedReader(new InputStreamReader(processOutput));
   String str1 = null;
   while ((str1 = bufIn.readLine()) != null) {
       System.out.println(str1 + "\n");
   }
   bufIn.close();
} catch (IOException e) {
   e.printStackTrace();
}
java processbuilder
1个回答
0
投票

你想要ProcessBuilder.startPipeline

ProcessBuilder raster2pgsql = new ProcessBuilder("raster2pgsql.exe",
    "-I", "-C", "-s", "4326", "-t", "256x256", "-l", "4,16",
    "C:\\raster\\sthlm.tif", "public.stockholm");
ProcessBuilder psql = new ProcessBuilder("psql.exe",
        "-h", "localhost", "-p", "5432", "-d", "rasterdata",
        "-U", "postgresuser");

raster2pgsql.redirectError(ProcessBuilder.Redirect.INHERIT);
psql.redirectError(ProcessBuilder.Redirect.INHERIT);
psql.redirectOutput(ProcessBuilder.Redirect.INHERIT);

List<Process> pipeline = ProcessBuilder.startPipeline(
    List.of(raster2pgsql, psql));

for (Process process : pipeline) {
    int exitCode = process.waitFor();
    if (exitcode != 0) {
        Optional<String> command = process.info().commandLine();
        if (!command.isPresent()) {
            command = process.info().command();
        }

        throw new IOException("Process exited with code " + exitCode
            + command.map(c -> ": " + c).orElse(""));
    }
}

您不能将

|
直接传递给进程,因为程序从不处理该字符; 通常是 shell(如 bash 或 cmd.exe)执行此操作,使输出和输入的管道对程序透明。 正如其他人提到的,解决方法是将整个命令传递给对
bash
cmd.exe
的显式调用,但随后您将需要自己转义命令参数。 最好让 ProcessBuilder.startPipeline 通过将命令序列直接传递给系统来处理一切。

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.