我正在尝试从java代码执行一个外部命令,但是我注意到Runtime.getRuntime().exec(...)和之间存在差异new ProcessBuilder(...).start().
使用时Runtime:
Process p = Runtime.getRuntime().exec(installation_path +
uninstall_path +
uninstall_command +
uninstall_arguments);
p.waitFor();
Run Code Online (Sandbox Code Playgroud)
exitValue为0,命令终止ok.
但是,有ProcessBuilder:
Process p = (new ProcessBuilder(installation_path +
uninstall_path +
uninstall_command,
uninstall_arguments)).start();
p.waitFor();
Run Code Online (Sandbox Code Playgroud)
退出值为1001,命令终止于中间,但waitFor返回.
我该怎么做才能解决问题ProcessBuilder?
我正在使用ProcessBuilder在Java中构建一个进程,如下所示:
ProcessBuilder pb = new ProcessBuilder()
.command("somecommand", "arg1", "arg2")
.redirectErrorStream(true);
Process p = pb.start();
InputStream stdOut = p.getInputStream();
Run Code Online (Sandbox Code Playgroud)
现在我的问题如下:我想捕获通过该进程的stdout和/或stderr的任何内容,并将其重定向到System.out异步.我希望进程及其输出重定向在后台运行.到目前为止,我发现这样做的唯一方法是手动生成一个新的线程,该线程将连续读取stdOut,然后调用适当的write()方法System.out.
new Thread(new Runnable(){
public void run(){
byte[] buffer = new byte[8192];
int len = -1;
while((len = stdOut.read(buffer)) > 0){
System.out.write(buffer, 0, len);
}
}
}).start();
Run Code Online (Sandbox Code Playgroud)
虽然这种方法很有效,但感觉有点脏.最重要的是,它为我提供了一个正确管理和终止的线程.有没有更好的方法来做到这一点?
我正在找出一种从Java调用exe并传入特定参数的机制.我能怎么做?
Process process = new ProcessBuilder("C:\\PathToExe\\MyExe.exe").start();
InputStream is = process.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line;
System.out.printf("Output of running %s is:", Arrays.toString(args));
while ((line = br.readLine()) != null) {
System.out.println(line);
}
Run Code Online (Sandbox Code Playgroud)
以前的代码有效.但是我无法传递参数.MyExe.exe接受参数.另一个问题是PathToExe有空格.ProcessBuilder似乎无法正常工作.例如:
C:\\User\\My applications\\MyExe.exe
Run Code Online (Sandbox Code Playgroud)
谢谢.
我已经开始使用以下代码进行处理
ProcessBuilder pb = new ProcessBuilder("cmd", "/c", "path");
try {
Process p = pb.start();
}
catch (IOException ex) {}
Run Code Online (Sandbox Code Playgroud)
现在我需要知道我刚刚开始的进程的pid.
我正在使用以下代码来启动进程构建器.我想知道如何将其输出重定向到String.
ProcessBuilder pb = new ProcessBuilder(System.getProperty("user.dir")+"/src/generate_list.sh", filename);
Process p = pb.start();
Run Code Online (Sandbox Code Playgroud)
我试过使用,ByteArrayOutputStream但它似乎没有用.
我一直在尝试使用Java的ProcessBuilder在Linux中启动应该"长期"运行的应用程序.该程序运行的方式是启动一个命令(在这种情况下,我正在启动一个媒体播放应用程序),允许它运行,并检查以确保它没有崩溃.例如,检查PID是否仍处于活动状态,然后重新启动该进程(如果已经死亡).
我现在遇到的问题是PID在系统中仍然存在,但应用程序的GUI挂起.我尝试将ProcessBuilder(cmd).start()转换为一个单独的线程,但这似乎并没有解决任何问题,正如我希望的那样.
基本上结果是,对于用户来说,程序APPEARS已经崩溃,但是杀死驱动ProcessBuilder.start()进程的Java进程实际上允许创建的进程恢复其正常行为.这意味着Java应用程序中的某些东西干扰了生成的进程,但此时我完全不知道是什么.(因此为什么我尝试将它分成另一个线程,似乎没有解决任何问题)
如果有人有任何意见/想法,请让我知道,因为我不能为我的生活想到如何解决这个问题.
编辑:我不关心从Process创建的I/O流,因此没有采取任何措施来解决这个问题 - 这是否会导致流程本身挂起?
我正在尝试在ubuntu的主目录中启动一个进程.我得到一个超出界限的数组异常.这是代码:
Process p = null;
ProcessBuilder pb = new ProcessBuilder();
pb.directory(new File("/home"));
p = pb.start();
Run Code Online (Sandbox Code Playgroud)
这是一个例外:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0
at java.lang.ProcessBuilder.start(ProcessBuilder.java:459)
at tester.Main.main(Main.java:31)
Java Result: 1
Run Code Online (Sandbox Code Playgroud) 我有一个在Playframework上运行的应用程序,它需要对一些视频文件进行编码.我用了
Process pr = Runtime.getRuntime().exec(execCode)
Run Code Online (Sandbox Code Playgroud)
为此(它完美地工作),但由于我需要输出流和错误流,我试图使用ProcessBuilder(也建议使用).
但我无法让它工作(在MacBook上测试).Runtime方法和ProcessBuilder之间有根本区别吗?
这是我的ProcessBuilder代码(替换时完全相同的代码Runtime.getRuntime().exec())
String execCode = "/opt/local/bin/ffmpeg -i file [...]";
ProcessBuilder pb = new ProcessBuilder(execCode);
pb.redirectErrorStream(true);
pb.directory(new File("/Users/[...]/data/"));
Process pr = pb.start();
Run Code Online (Sandbox Code Playgroud)
这是控制台输出:
11:00:18,277 ERROR ~ There was a problem with with processing MediaFile[13] with error Error during coding process: Cannot run program "/opt/local/bin/ffmpeg -i /Users/[...]/data/media/1/1/test.mov [...] /Users/[...]/data/media/1/13/encoded.mp3" (in directory "/Users/[...]/data"): error=2, No such file or directory
java.lang.Exception: Error during coding process: Cannot run program "/opt/local/bin/ffmpeg -i /Users/Luuk/Documents/Java/idoms-server/data/media/1/1/test.mov -y -f mpegts -acodec libmp3lame …Run Code Online (Sandbox Code Playgroud) 我有一个Java程序,它是ProcessBuilder从另一个Java程序启动的.
System.exit(0)从子程序调用,但对于我们的一些用户(在Windows上),java.exe与子项关联的进程不会终止.子程序没有关闭挂钩,也没有SecurityManager可能停止System.exit()终止VM的挂钩.我无法在Linux或Windows Vista上自行重现此问题.到目前为止,问题的唯一报告来自两个Windows XP用户和一个Vista用户,使用两个不同的JRE(1.6.0_15和1.6.0_18),但他们每次都能够重现问题.
任何人都可以提出为什么JVM无法在之后终止System.exit(),然后只在某些机器上终止的原因?
编辑1:我让用户安装JDK,这样我们就可以从违规的虚拟机中获取一个线程转储.用户告诉我的是,一旦他点击我的菜单中的"退出"项目,VM进程就会从VisualVM中消失---但是,根据Windows任务管理器,该进程尚未终止,无论多长时间用户等待(分钟,小时),它永远不会终止.
编辑2:我现在已经确认Process.waitFor()在父程序中永远不会返回至少一个有问题的用户.总而言之:孩子VM似乎已经死了(VisualVM甚至没有看到它),但是父母仍然认为这个过程是实时的,Windows也是如此.
我想将java进程输出重定向到父java进程的标准输出.
使用ProcessBuilder类如下:
public static void main(String[] args) {
ProcessBuilder processBuilder = new ProcessBuilder("cmd");
processBuilder.directory(new File("C:"));
processBuilder.redirectErrorStream(true); // redirect error stream to output stream
processBuilder.redirectOutput(ProcessBuilder.Redirect.INHERIT);
}
Run Code Online (Sandbox Code Playgroud)
我原以为"cmd"的输出,如:
Microsoft Windows [版本6.1.7601]版权所有(c)2009 Microsoft Corporation.Tousdroitsréservés.
显示在用于运行java程序的DOS控制台中.但是在DOS控制台中根本没有显示任何内容.
在讨论的其他主题中,我看到了使用BufferedReader类的解决方案:但是在这里我希望过程的输出直接显示在标准输出中,而不使用任何BufferedReader或"while read loop".可能吗?
谢谢.
java ×10
processbuilder ×10
process ×2
runtime.exec ×2
stream ×2
crash ×1
exe ×1
exit ×1
inheritance ×1
linux ×1
pid ×1
redirect ×1
ubuntu ×1
unix ×1