【问题标题】:execute an external command in java在java中执行外部命令
【发布时间】:2010-10-15 14:58:29
【问题描述】:

有没有办法在 java 中执行一个命令,而不会受到使用 ProcessBuilder 的启动开销(缓慢)的影响?

更多细节:我正在使用 im4java,这是一个内部使用 ProcessBuilder 执行 imagemagick 程序的 java 库。它很慢。我创建了一个小型单元测试,表明 ProcessBuilder(不是 im4java)是问题所在。缓慢是使用 ProcessBuilder 的启动开销。我发现互联网上的帖子说 processbuider 有开销,所以不仅仅是我说的。

List<String> commands = new ArrayList<String>();
commands.add("C:\\PROGRA~2\\ImageMagick-6.6.4-Q16\\convert.exe");
commands.add("dog.jpg");
commands.add("output.jpg");
ProcessBuilder processBuilder = new ProcessBuilder(commands);
Process start = processBuilder.start();
start.waitFor();

【问题讨论】:

  • 性能真的是个问题,还是只是在测试过程中“烦人”?鼓励使用 ProcessBuilder 比使用 Runtime.exec() 有几个很好的理由 (javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html)。
  • 是的,性能是个问题。虽然我错了 ProcessBuilder 降低性能的时间。它不会添加太多。似乎有几个地方速度变慢了,所以它正在加起来。

标签: java imagemagick


【解决方案1】:

不建议这样做,但您可以编写一个 JNI 库来执行 ProcessBuilder 正在执行的相同操作。也许你的会更快,但我不会指望它,而且你会失去跨平台兼容性。

我们在这里说话有多慢?我自己使用ProcessBuilder 来运行Git 命令(还没有机会研究JGit),它看起来足够活泼。你可能在 Linux 上运气更好,因为开销实际上可能是在 Windows 重量级进程创建中。

【讨论】:

  • Windows 1 秒,Linux 2 秒。 (windows机器的硬件比linux机器好得多)当我直接运行程序(不是java)时,它会在几毫秒内运行。
  • 我刚刚查看了ProcessBuilderRuntime.exec() 代码。 Runtime.exec() 使用 ProcessBuilder,而 ProcessBuilder 唯一可能的减速是将列表转换为字符串数组,然后复制该数组。如果您真的需要更快的速度,您可能需要编写自己的原生实现。
【解决方案2】:
Runtime.getRuntime().exec(...)  

可用于运行外部命令。您可以将您的 List 转换为命令数组或字符串以传递给 exec()。

【讨论】:

  • 谢谢,但我也这样做了。它似乎有相同的开销。你知道不一样吗? (我的测试用例可能会产生误导)
  • 不。正如另一位评论者指出的那样,您已经在使用执行另一个应用程序的首选方法。如果这不是更快,那么您可能无能为力。
  • Runtime.getRuntime().exec() 使用ProcessBuilder
猜你喜欢
  • 2012-04-09
  • 2013-04-16
  • 2012-04-15
  • 1970-01-01
  • 2013-11-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-13
相关资源
最近更新 更多