背景
项目需求中涉及java调用.bat文件进行图像处理,先直接上简略版程序
1 public void draw(){ 2 3 //调用bat脚本进行图像处理 4 Process process = null; 5 InputStream in = null; 6 try { 7 process = Runtime.getRuntime().exec("startup.bat"); 8 9 //输出测试 10 // in = process.getInputStream(); 11 // String line; 12 // BufferedReader br = new BufferedReader(new InputStreamReader(in)); 13 // while ((line = br.readLine()) != null) { 14 // System.out.println(line); 15 // } 16 17 //等待 18 process.waitFor(); 19 20 } catch (Exception e) { 21 22 } finally { 23 process.destroy(); 24 } 25 }
JAVA使用遇到的问题描述
一般需要调用系统命令时,大部分人第一反应肯定是使用Runtime.getRuntime().exec(command)返回一个process对象,再调用process.waitFor()来等待命令执行结束,获取执行结果。
调试的时候发现很奇怪的现象,process.waitFor();一直没有结束,导致线程阻塞再次,强行关闭程序后,发现图像处理只进行了一部分。
于是打算打印process的输出,看是否是图像脚本出现异常。
在启用输出测试的下发代码后,发现process的输出一切正常,process.waitFor()一直再等待,并未结束,此时强行关闭程序后,发现图像处理并之前多操作了一部分
根据现象并查看了JDK的帮助文档,如下
因此,可以得出结论:如果外部程序不断在向标准输出流(对于jvm来说就是输入流)和标准错误流写数据,而JVM不读取的话,当缓冲区满之后将无法继续写入数据,最终造成阻塞在waitFor()这里。
解决方法:在waitFor()之前,利用单独两个线程,分别处理process的getInputStream()和getErrorSteam(),防止缓冲区被撑满,导致阻塞;
修改后代码
1 public class test { 2 3 public void draw(){ 4 5 //调用bat脚本进行图像处理 6 Process process = null; 7 InputStream in = null; 8 try { 9 process = Runtime.getRuntime().exec("startup.bat"); 10 11 //输出测试 12 // in = process.getInputStream(); 13 // String line; 14 // BufferedReader br = new BufferedReader(new InputStreamReader(in)); 15 // while ((line = br.readLine()) != null) { 16 // System.out.println(line); 17 // } 18 //新启两个线程 19 new DealProcessSream(process.getInputStream()).start(); 20 new DealProcessSream(process.getErrorStream()).start(); 21 22 process.waitFor(); 23 24 } catch (Exception e) { 25 26 } finally { 27 process.destroy(); 28 } 29 } 30 }
1 public class DealProcessSream extends Thread { 2 private InputStream inputStream; 3 4 public DealProcessSream(InputStream inputStream) { 5 this.inputStream = inputStream; 6 } 7 8 public void run() { 9 InputStreamReader inputStreamReader = null; 10 BufferedReader br = null; 11 try { 12 inputStreamReader = new InputStreamReader( 13 inputStream); 14 br = new BufferedReader(inputStreamReader); 15 // 打印信息 16 // String line = null; 17 // while ((line = br.readLine()) != null) { 18 // System.out.println(line); 19 // } 20 // 不打印信息 21 while (br.readLine() != null); 22 } catch (IOException ioe) { 23 ioe.printStackTrace(); 24 }finally { 25 try { 26 br.close(); 27 inputStreamReader.close(); 28 } catch (IOException e) { 29 e.printStackTrace(); 30 } 31 } 32 33 } 34 }
原文地址:https://www.cnblogs.com/MacrossFT/p/12038479.html
时间: 2024-11-07 03:50:31