`
zhuyufufu
  • 浏览: 139569 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

Java 进程执行外部程序,造成外部程序阻塞的一种原因

阅读更多
  前一阵子在研究文档展示时使用了java进程直接调用外部程序。

  其中遇到一个问题花了好长时间才解决。

  这个问题就是外部程序直接执行没什么问题,但是当使用Java进程执行时外部程序就阻塞在那儿不动了。而且这个外部程序在处理某些文件时使用Java进程执行是没问题的

  查了好多资料,差点就动手翻Java源码了,最后结合一篇文章(忘记出处了),想到了输出流会阻塞进程执行

  Java进程执行有一个输入流,两个输出流(相对于外部程序)。当两个输出流有内容输出,而Java执行程序没有及时清空输出流时就会阻塞进程。

  现贴出代码,希望能帮助到有需要的同行:

/**
	 * pdf转swf函数
	 * @param path 输入输出文件路径
	 * @param inputFileName 输入文件名
	 * @param outputFileName 输出文件名
	 * @return File 生成的swf文件
	 */
	private static File toSwf(String sourceFile, String destFile, String command) {
		long beginTime = System.nanoTime();
		Runtime rt = Runtime.getRuntime();
		try {
			Process process = rt.exec(command);
			
			final InputStream isNormal = process.getInputStream();
			new Thread(new Runnable() {
			    public void run() {
			        BufferedReader br = new BufferedReader(new InputStreamReader(isNormal)); 
			        StringBuilder buf = new StringBuilder();
					String line = null;
					try {
						while((line = br.readLine()) != null){
							buf.append(line + "\n");
						}
					} catch (IOException e) {
						e.printStackTrace();
					}
					System.out.println("输出结果为:" + buf);
			    }
			}).start(); // 启动单独的线程来清空process.getInputStream()的缓冲区
			
			InputStream isError = process.getErrorStream();
			BufferedReader br2 = new BufferedReader(new InputStreamReader(isError)); 
			StringBuilder buf = new StringBuilder();
			String line = null;
			while((line = br2.readLine()) != null){
				buf.append(line + "\n");
			}
			System.out.println("错误输出结果为:" + buf);
			
			try {
				process.waitFor();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}

		} catch (IOException e) {
			e.printStackTrace();
		}
		long endTime = System.nanoTime();
		System.out.println("转swf耗时: " + (endTime - beginTime) / 1000000000 + " 秒  " + sourceFile);
		return new File(destFile);
	}
0
0
分享到:
评论

相关推荐

    Java 进程执行外部程序造成阻塞的一种原因

    然而,这样的操作可能会遇到一个常见的问题,即Java进程执行外部程序时发生阻塞,导致程序运行停滞。这个问题可能由多种原因引起,但在这里我们将重点关注一个具体的因素:输出流未被正确处理。 当Java进程执行外部...

    Java调用外部程序命令

    当使用Java调用外部程序时,可能会遇到程序无法正常退出的情况,通常这是由于进程的输入/输出流未被正确处理造成的。 - **解决方案1:** 关闭标准输入流 当外部程序等待标准输入时,如果没有关闭标准输入流,会...

    用java编的适用于操作系统课程设计的线程-进程管理

    而"进程管理"可能包含的是通过Java实现的进程控制和通信的示例代码,比如如何执行外部程序、读取其输出、管理进程间通信等。 总的来说,这个课程设计项目通过Java语言,让学生实际操作线程和进程的管理,加深对操作...

    Java调用系统执行程序(OS Command)

    总的来说,Java通过`Runtime`和`ProcessBuilder`提供了一种强大的方式来调用系统命令和执行外部程序。然而,必须谨慎处理这些调用,以防止潜在的安全问题,并确保正确处理命令的输入、输出和错误流。在实际开发中,...

    java执行可执行文件或批处理

    在Java中执行外部可执行文件或批处理脚本是一种常见的需求,尤其是在需要调用系统级别的工具或者与操作系统进行交互时。通过Java的`Runtime`类及其提供的方法,我们可以方便地实现这一功能。本文将详细介绍如何在...

    Java基于Runtime调用外部程序出现阻塞的解决方法

    这通常发生在Java程序启动了外部进程后,并没有等待外部程序执行完成就继续执行了后续代码,导致程序的逻辑错误或预期结果未得到。 为了解决这个问题,我们需要确保Java程序在调用外部程序后进行阻塞,直到外部程序...

    操作系统进程调度java源代码

    在这个主题中,“操作系统进程调度java源代码”提供了实现进程调度算法的一种编程实践。 进程是操作系统中的基本执行单元,它包含了程序、数据以及其执行的上下文。在操作系统中,进程调度是核心功能之一,它的主要...

    操作系统作业(进程控制管理实现)

    实验要求:进程控制管理实现 ...每次事件处理后应形象地显示出当前系统中的执行进程是哪一个,就绪队列和阻塞队列分别包含哪些进程。 自己做的 java图形界面 增加了内存管理的模拟并采用了最佳适应算法。

    Java中使用Runtime和Process类运行外部程序.docx

    这两个类提供了一种机制,使得Java应用程序能够与操作系统进行交互,执行系统命令或者运行其他可执行文件。下面我们将详细探讨如何使用这两个类以及在实际应用中需要注意的问题。 `Runtime`类是每个Java应用程序都...

    调用外部程序

    5. **Java的Runtime.exec()**:在Java中,可以使用`Runtime.getRuntime().exec()`方法启动外部程序,或者使用`ProcessBuilder`类进行更复杂的控制。 关于“窗体的绑定”这部分,通常是指在图形用户界面(GUI)应用...

    java调用exe可执行文件

    但需要注意的是,由于Web应用的安全性和多用户并发性,直接在JSP中执行外部程序可能会带来安全风险,因此通常不推荐在JSP中直接操作。 在调用.exe文件时,还应注意以下几点: 1. **路径问题**:确保.exe文件的路径...

    操作系统实验之进程管理(java实现)

    在这个操作系统实验中,我们将聚焦于进程管理,这是一个至关重要的概念,因为它关乎到系统如何有效地调度和执行多个程序。Java作为一种多平台支持的编程语言,被选中来实现这个实验,这展示了其在系统级编程中的应用...

    JAVA执行DOS命令分析

    总结来说,Java通过`Runtime.exec()`方法提供了一种灵活的方式来执行DOS命令,但同时也需要开发者注意处理子进程的生命周期,尤其是标准输入/输出/错误流的管理,以及跨平台兼容性问题。在进行文件操作时,特别是在...

    Java 执行本地脚本携带多参数

    总之,Java通过`Runtime`或`ProcessBuilder`提供了一种方式来执行本地脚本并传递参数。正确处理输出流、错误流以及配置工作目录和环境变量,是成功执行脚本的关键。在实际项目中,根据需求选择合适的执行方式,并...

    java中调用本地exe文件

    在Java中,可以通过`java.lang.Runtime`类或者`java.lang.ProcessBuilder`类来启动外部程序(exe文件)。这两种方式都可以实现同样的功能,但在实际开发过程中,选择哪一种方式取决于具体需求和个人偏好。 - **...

    进程交互案例

    Java作为一种跨平台的编程语言,提供了丰富的API和工具来支持进程级交互。本篇将深入探讨Java中实现进程交互的方法以及如何利用这些方法来监控进程。 在Java中,`java.lang.ProcessBuilder`类和`java.lang.Process`...

    Java调用Linux命令

    当我们调用`Runtime.getRuntime().exec(command)`时,实际上是在当前Java进程中启动了一个新的子进程。这个子进程没有自己的控制台或终端窗口,其标准输入、标准输出和标准错误都会被重定向到父进程的相应流中。具体...

    java批处理[归类].pdf

    5. 处理标准输出:当执行的程序有大量标准输出时,可能会导致DOS窗口不自动关闭,造成Java程序阻塞。这时,可以使用`Process`的输入流来读取并处理标准输出,防止缓冲区溢出,如: ```java Process process = ...

    进程调度与内存管理:这是我花了很长时间写的一个实验,界面非常美观,完成了进程调度的各个状态包括,就绪,运行,阻塞,挂起,并用画图来表示内存的分配情况,自我感觉还是不错的

    5. **内存碎片**:在连续分配或分页/分段系统中,内存可能会产生两种类型的碎片——内部碎片(分配给进程但未使用的内存)和外部碎片(无法分配给进程的小块内存)。实验可能探讨了如何通过紧凑或动态调整内存布局来...

Global site tag (gtag.js) - Google Analytics