java,process与runtime()的使用及调用cmd命令阻塞的亚博vip888的解决方案-亚博电竞手机版

java process与runtime()使用

java调用cmd执行bat文件有时会出现卡死的现象,当时感觉很迷惑,后来查资料,本来一般都是这样来调用程序并获取进程的输出流的,但是我在windows上执行这样的调用的时候却总是在while那里被堵塞了,结果造成ffmpeg程序在执行了一会后不再执行,这里从官方的参考文档中我们可以看到这是由于缓冲区的问题,由于java进程没有清空ffmpeg程序写到缓冲区的内容,结果导致ffmpeg程序一直在等待。

在网上也查找了很多这样的问题,不过说的都是使用单独的线程来进行控制,我也尝试过很多网是所说的方法,可一直没起什么作用。

一直认为是getinputstream的缓冲区没有被清空,不过问题确实是缓冲区的内容没有被清空,但不是getinputstream的,而是geterrorstream的缓冲区,这样问题就得到解决了。

所以我们在遇到java调用外部程序而导致线程阻塞的时候,可以考虑使用两个线程来同时清空process获取的两个输入流,如下这段程序:

public string excutebatfile(string file, boolean isclosewindow) { string cmdcommand = null; string res = null; if(isclosewindow) { cmdcommand = "cmd.exe /c " file; }else { cmdcommand = "cmd.exe /k " file; } stringbuilder stringbuilder = new stringbuilder(); process process = null; try { process = runtime.getruntime().exec(cmdcommand); final inputstream is1 = process.getinputstream(); new thread(new runnable() { public void run() { bufferedreader bufferedreader = null; string line = null; try { bufferedreader = new bufferedreader( new inputstreamreader(is1, "gbk")); while((line=bufferedreader.readline()) != null) { stringbuilder.append(line "\n"); } is1.close(); } catch (exception e) { // todo auto-generated catch block e.printstacktrace(); } } }).start(); // 启动单独的线程来清空p.getinputstream()的缓冲区 inputstream is2 = process.geterrorstream(); bufferedreader br2 = new bufferedreader(new inputstreamreader(is2)); stringbuilder buf = new stringbuilder(); // 保存输出结果流 string line2 = null; while((line2 = br2.readline()) != null) buf.append(line2); // log.info("----res:----" stringbuilder "&" buf); return stringbuilder "&" buf; } catch (exception e) { e.printstacktrace(); return e.tostring(); } }

通过这样我们使用一个线程来读取process.getinputstream()的输出流,使用另外一个线程来获取process.geterrorstream()的输出流,这样我们就可以保证缓冲区得到及时的清空而不担心线程被阻塞了。

当然根据需要你也可以保留process.getinputstream()流中的内容,这个就看调用的程序的处理了。

java process执行cmd命令流阻塞处理

代码如下:

public static void runcmd() { process process = null; bufferedreader bufferedreader = null; try { logger.getlogger(systemservice.class).info("============= 开始重启机器 ============="); process = runtime.getruntime().exec("cmd.exe /c shutdown -r -f -t 0"); bufferedreader = new bufferedreader(new inputstreamreader(new bufferedinputstream(process.getinputstream()), charset.forname("gb2312"))); // 开启线程读取错误输出,避免阻塞 new streaminformatonthread(process.geterrorstream(), "error").start(); string outstr; while ((outstr = bufferedreader.readline()) != null) { logger.getlogger(systemservice.class).info("readline -------> : " outstr); } logger.getlogger(systemservice.class).info("============= 重启机器完成 ============="); } catch (ioexception e) { logger.getlogger(systemservice.class).error("============= 重启机器失败 ============="); e.printstacktrace(); } finally { if (process != null) { process.destroy(); } if (bufferedreader != null) { try { bufferedreader.close(); } catch (ioexception e) { e.printstacktrace(); } } } }

import java.io.*; /** * @description:流阻塞处理 * @author: zhangwenchao * @date: 2019/7/9 11:35 */ public class streaminformatonthread extends thread { private inputstream is; private string str; private logger logger = logger.getlogger(streaminformatonthread.class); public streaminformatonthread(inputstream is, string str) { this.is = is; this.str = str; } public void run() { bufferedreader out = null; try { out = new bufferedreader(new inputstreamreader(is, "gbk")); string line; while ((line = out.readline()) != null) { if (str.equals("error")) { logger.info("errorstream --------> :" line); } else { logger.info("outline ---------> :" line); } } } catch (unsupportedencodingexception e) { e.printstacktrace(); } catch (ioexception e) { e.printstacktrace(); } finally { if (out != null) { try { out.close(); } catch (ioexception e) { e.printstacktrace(); } } } } }

以上为个人经验,希望能给大家一个参考,也希望大家多多支持趣讯吧。

展开全文
内容来源于互联网和用户投稿,文章中一旦含有亚博电竞手机版的联系方式务必识别真假,本站仅做信息展示不承担任何相关责任,如有侵权或涉及法律问题请联系亚博电竞手机版删除

最新文章

网站地图