标签: processbuilder

ProcessBuilder和Runtime.exec()之间的区别

我正在尝试从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

java runtime.exec processbuilder

93
推荐指数
4
解决办法
11万
查看次数

ProcessBuilder:转发stdout和stderr启动进程而不阻塞主线程

我正在使用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 processbuilder

88
推荐指数
5
解决办法
9万
查看次数

Java编程:从Java调用exe并传递参数

我正在找出一种从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)

谢谢.

java exe processbuilder

84
推荐指数
2
解决办法
12万
查看次数

如何获得我刚刚在java程序中启动的进程的PID?

我已经开始使用以下代码进行处理

 ProcessBuilder pb = new ProcessBuilder("cmd", "/c", "path");
 try {
     Process p = pb.start();       
 } 
 catch (IOException ex) {}
Run Code Online (Sandbox Code Playgroud)

现在我需要知道我刚刚开始的进程的pid.

java pid process processbuilder

66
推荐指数
7
解决办法
10万
查看次数

如何将Process Builder的输出重定向到字符串?

我正在使用以下代码来启动进程构建器.我想知道如何将其输出重定向到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 stream processbuilder

56
推荐指数
7
解决办法
8万
查看次数

Java ProcessBuilder:结果进程挂起

我一直在尝试使用Java的ProcessBuilder在Linux中启动应该"长期"运行的应用程序.该程序运行的方式是启动一个命令(在这种情况下,我正在启动一个媒体播放应用程序),允许它运行,并检查以确保它没有崩溃.例如,检查PID是否仍处于活动状态,然后重新启动该进程(如果已经死亡).

我现在遇到的问题是PID在系统中仍然存在,但应用程序的GUI挂起.我尝试将ProcessBuilder(cmd).start()转换为一个单独的线程,但这似乎并没有解决任何问题,正如我希望的那样.

基本上结果是,对于用户来说,程序APPEARS已经崩溃,但是杀死驱动ProcessBuilder.start()进程的Java进程实际上允许创建的进程恢复其正常行为.这意味着Java应用程序中的某些东西干扰了生成的进程,但此时我完全不知道是什么.(因此为什么我尝试将它分成另一个线程,似乎没有解决任何问题)

如果有人有任何意见/想法,请让我知道,因为我不能为我的生活想到如何解决这个问题.

编辑:我不关心从Process创建的I/O流,因此没有采取任何措施来解决这个问题 - 这是否会导致流程本身挂起?

java linux crash multithreading processbuilder

32
推荐指数
4
解决办法
2万
查看次数

如何使用ProcessBuilder设置工作目录

我正在尝试在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)

java unix ubuntu process processbuilder

31
推荐指数
1
解决办法
4万
查看次数

ProcessBuilder在Mac上提供"没有这样的文件或目录",而Runtime().exec()工作正常

我有一个在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 runtime.exec processbuilder playframework

29
推荐指数
1
解决办法
3万
查看次数

是什么导致Java在System.exit()之后继续运行?

我有一个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 exit processbuilder

20
推荐指数
3
解决办法
3万
查看次数

ProcessBuilder重定向到标准输出

我想将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 inheritance redirect stream processbuilder

20
推荐指数
2
解决办法
2万
查看次数