问题描述
我不熟悉使用 ProcessBuilder
对象在 Java 中运行命令。我的问题是,当我将环境变量放入 builder.command(...)
方法时,它不起作用。但是,当我对环境变量的字符串进行硬编码时,它运行良好。下面是我的代码以及帮助说明我在做什么的解释:
ProcessBuilder builder = new ProcessBuilder();
builder.directory(f);
System.out.println("The user's chosen directory is: "+builder.directory());
Map<String,String> environment = builder.environment();
environment.put("WINDOW",w);
environment.put("AUdio",a);
environment.forEach((key,value)->System.out.println("key is "+key+" "+"value: "+value));
builder.command("ffmpeg","-i","$WINDOW","$AUdio","-vcodec","copy","output.mp4");
Process pr= builder.start();
说明/目的:
基本上我有一个 JButton
,当用户点击它时会触发 ActionListener
。如果他们愿意,我正在尝试使用 ffmpeg
将音频和视频文件一起转换为一个文件。上面的这段代码将被执行,我试图在其中获取他们在我的应用程序中选择的文件的目录,以存储前面提到的两个文件。通过使用 builder.directory(f)
,我可以将 builder
的当前目录更改为用户的当前目录。然后我创建了一个名为 environment
的映射,我可以在其中添加两个名为 WINDOW
和 AUdio
的环境变量。两个环境。变量被分配文件名,这样文件名被分配给两个变量 w
和 a
,它们是字符串类型。我确实检查过它们是否在地图上,并且确实在。然后我尝试使用 builder.command(...)
方法制作我的指令集,然后使用 builder.start()
启动该过程。
结论:
但是,未创建单个output.mp4
文件,当我使用 waitFor()
方法检查我的进程时,我得到一个“1”。相反,当我不使用 env.变量并将文件名硬编码在 env.变量,它工作正常。那么,我的 builder.command(..)
到底做错了什么?谢谢。
解决方法
我觉得最简单的解决方案是:
builder.command("ffmpeg","-i",w,a,"-vcodec","copy","output.mp4");
如果您只想使用环境变量来注入命令行参数,则无需设置环境变量。
但是,如果你确实想通过环境变量来做,那么简单的方法是使用一个子shell来完成所有的命令行解析和扩展;例如
builder.command("/bin/sh","-c","ffmpeg -i $WINDOW -i $AUDIO -vcodec copy output.mp4");
您还可以使用引用、通配符、管道、重定向和所有其他花哨的 shell 功能。