本文实例讲述了Java基于Runtime调用外部程序出现阻塞的解决方法, 是一个很实用的技巧。分享给大家供大家参考。具体分析如下:
有时候在java代码中会调用一些外部程序,比如SwfTools来转换swf、ffmpeg来转换视频等。如果你的代码这样写:Runtime.getRuntime().exec(command),会发现程序一下就执行完毕,而在命令行里要执行一会,是因为java没有等待外部程序的执行完毕,此时就需要使用阻塞,来等待外部程序执行结果:
InputStream stderr = process.getInputStream(); InputStreamReader isr = new InputStreamReader(stderr, "GBK"); BufferedReader br = new BufferedReader(isr); String line = null; while ((line = br.readLine()) != null) System.out.println(line); int exitValue = process.waitFor();
对于一般的外部程序使用上面的阻塞代码就可以,至少pdf2swf.exe是没有问题的。
但是紧接着又发现对于ffmpeg来说,以上代码会让程序卡住不动,需要使用另一种方式,封装成了一个方法,如下:
public int doWaitFor(Process process) { InputStream in = null; InputStream err = null; int exitValue = -1; // returned to caller when p is finished try { in = process.getInputStream(); err = process.getErrorStream(); boolean finished = false; // Set to true when p is finished while (!finished) { try { while (in.available() > 0) { // Print the output of our system call Character c = new Character((char) in.read()); System.out.print(c); } while (err.available() > 0) { // Print the output of our system call Character c = new Character((char) err.read()); System.out.print(c); } // Ask the process for its exitValue. If the process // is not finished, an IllegalThreadStateException // is thrown. If it is finished, we fall through and // the variable finished is set to true. exitValue = process.exitValue(); finished = true; } catch (IllegalThreadStateException e) { // Process is not finished yet; // Sleep a little to save on CPU cycles Thread.currentThread().sleep(500); } } } catch (Exception e) { e.printStackTrace(); } finally { try { if (in != null) { in.close(); } } catch (IOException e) { e.printStackTrace(); } if (err != null) { try { err.close(); } catch (IOException e) { e.printStackTrace(); } } } return exitValue; }
希望本文所述对大家Java程序设计的学习有所帮助。
以上文章从网上转载,当已经找不到出处,在实际过程中,会遇到乱码的情况
public int doWaitFor(Process process, JobInfo jobInfo) { InputStream in = null; InputStream err = null; int exitValue = -1; // returned to caller when p is finished ByteBuffer byteBuffer = ByteBuffer.allocate(512); try { in = process.getInputStream(); err = process.getErrorStream(); boolean finished = false; // Set to true when p is finished while (!finished) { try { while (in.available() > 0) { if(byteBuffer.position() == byteBuffer.capacity()) { ByteBuffer _byteBuffer = ByteBuffer.allocate(byteBuffer.capacity() + 512); _byteBuffer.put(byteBuffer.array(), 0, byteBuffer.capacity()); byteBuffer = _byteBuffer; } // Print the output of our system call byte _byte = (byte) in.read(); byteBuffer.put(_byte); Character c = new Character((char) _byte); // logMessage.append(c); System.out.print(c); } while (err.available() > 0) { if(byteBuffer.position() == byteBuffer.capacity()) { ByteBuffer _byteBuffer = ByteBuffer.allocate(byteBuffer.capacity() + 512); _byteBuffer.put(byteBuffer.array(), 0, byteBuffer.capacity()); byteBuffer = _byteBuffer; } // Print the output of our system call byte _byte = (byte) err.read(); byteBuffer.put(_byte); Character c = new Character((char) _byte); // logMessage.append(c); System.out.print(c); } // Ask the process for its exitValue. If the process // is not finished, an IllegalThreadStateException // is thrown. If it is finished, we fall through and // the variable finished is set to true. exitValue = process.exitValue(); finished = true; } catch (IllegalThreadStateException e) { // Process is not finished yet; // Sleep a little to save on CPU cycles Thread.currentThread().sleep(500); } } } catch (Exception e) { e.printStackTrace(); } finally { try { if (in != null) { in.close(); } } catch (IOException e) { e.printStackTrace(); } if (err != null) { try { err.close(); } catch (IOException e) { e.printStackTrace(); } } } try { String logMessage = new String(byteBuffer.array(), 0, byteBuffer.position(), "gbk"); System.out.print(logMessage); jobInfo.setLogMessage(logMessage); jobInfo.setExecuteResult(true); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } return exitValue; }
...
相关推荐
通过上述示例,我们可以看到如何在Java中正确地调用外部程序,并解决了常见的阻塞问题。此外,还介绍了如何使用WMIC命令来重启服务,这对于自动化运维或开发中管理Windows服务非常有用。希望本文能帮助您更好地理解...
在Java中,调用外部程序的主要方法是使用`Runtime`类或`ProcessBuilder`类。`Runtime.getRuntime().exec()`方法是最常用的,它可以执行系统命令并返回一个`Process`对象,用于管理外部程序的生命周期。下面是一个...
调用外部程序后,记得关闭相关的输入输出流,并调用`destroy()`方法结束子进程,以避免资源泄露。 6. **异常处理**: 执行外部命令可能会抛出IOException,需要捕获并处理。 以上就是关于"java中调用控制台程序...
总结来说,Java通过`Runtime.exec()`方法提供了与操作系统交互的能力,允许我们在Java程序中执行外部程序和命令。然而,为了保证程序的健壮性和安全性,需要对可能出现的异常进行处理,并且谨慎处理用户输入,避免...
1. **调用外部程序** - 使用`Runtime.getRuntime().exec()`方法创建一个子进程来执行指定的可执行程序。例如: ```java Process process = Runtime.getRuntime().exec(".\\p.exe"); ``` - `exec()`方法返回一个...
这通常涉及到事件处理和线程管理,确保调用外部程序不会阻塞主线程,导致用户界面冻结。 至于“与外部程序之间的通信”,可以有以下几种方式: 1. **管道(Pipes)**:创建一个管道,使得父进程和子进程之间可以进行...
总的来说,Java通过`Runtime`和`ProcessBuilder`提供了一种强大的方式来调用系统命令和执行外部程序。然而,必须谨慎处理这些调用,以防止潜在的安全问题,并确保正确处理命令的输入、输出和错误流。在实际开发中,...
Java语言在执行外部程序或与操作系统交互时,通常会用到`java.lang.Runtime`类。这个类提供了运行时环境的接口,允许Java程序执行系统命令。然而,直接使用`Runtime`类进行命令行操作可能会比较繁琐,需要处理进程的...
6. **进程通信**:Java的`Runtime.exec()`方法可能需要正确处理标准输出和错误输出,以避免缓冲区溢出导致的进程阻塞。 解决这些问题通常需要结合日志分析,调试代码,以及对Linux和Java系统调用的深入理解。在实际...
在Java中,可以通过`java.lang.Runtime`类或者`java.lang.ProcessBuilder`类来启动外部程序(exe文件)。这两种方式都可以实现同样的功能,但在实际开发过程中,选择哪一种方式取决于具体需求和个人偏好。 - **...
但需要注意的是,由于Web应用的安全性和多用户并发性,直接在JSP中执行外部程序可能会带来安全风险,因此通常不推荐在JSP中直接操作。 在调用.exe文件时,还应注意以下几点: 1. **路径问题**:确保.exe文件的路径...
在Java编程中,有时我们需要在程序中调用操作系统级别的命令或者执行外部程序,这就涉及到Java中的`Runtime`和`Process`类。这两个类提供了一种机制,使得Java应用程序能够与操作系统进行交互,执行系统命令或者运行...
4. **异常处理**:在调用外部程序时,可能会遇到找不到文件、权限问题等异常,需要进行适当的异常处理。例如,当命令执行失败时,`exec()`方法会抛出`IOException`。 5. **DatToWav.java**:根据提供的文件名,这...
接着,了解Java如何调用外部程序。Java提供了`Runtime.getRuntime().exec()`方法或`ProcessBuilder`类来执行系统命令。例如,我们可以使用以下Java代码来执行一个简单的FFmpeg命令: ```java String command = ...
在Java编程中,调用命令行是常见的任务之一,它允许开发者执行系统级别的操作,如运行外部程序、管理系统资源或进行文件操作。本篇将详细讲解如何在Java中调用命令行,以及相关的知识点。 首先,Java通过`Runtime`...
在Oracle数据库中,有时我们需要调用外部程序来执行特定任务,比如数据处理、文件压缩等。本篇将介绍如何利用Java Source在Oracle中调用外部程序,并通过一个具体的示例来详细阐述整个过程。 首先,我们需要创建一...
通过以上介绍,我们不仅了解了如何在Java程序中调用Linux命令的基本原理,还学习了如何通过`Runtime.exec()`方法创建子进程以及如何控制这些子进程。这对于开发需要与操作系统交互的应用程序是非常有用的。
ProcessBuilder 非阻塞是调用是指在 Java 中使用 ProcessBuilder 类来执行外部命令或程序时,如何实现非阻塞调用。 在 Java 中,使用 ProcessBuilder 类可以执行外部命令或程序,例如执行系统命令、运行可执行文件...