如果我运行此命令:
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();
}
你想要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 通过将命令序列直接传递给系统来处理一切。