当前位置: 首页 > news >正文

北京市网站建设_网站建设公司_需求分析_seo优化

网站首页幻灯片不显示,建设系统网站首页,免费linux云服务器,国内优秀网站网址※※Java调用Runtime.exec()要注意的问题标签#xff1a;execJavaRuntime字体#xff1a;【默认中大】 http://it.superkoo.com/#/topic/479/ 最近开发一个项目需要在JAVA中调用VC写的一个EXE程序#xff0c;首先想到的方法肯定是用Runtime.exec()#xff0c;但一写就发现execJavaRuntime字体【默认中大】 http://it.superkoo.com/#/topic/479/ 最近开发一个项目需要在JAVA中调用VC写的一个EXE程序首先想到的方法肯定是用Runtime.exec()但一写就发现事情并没有那么的简单。后来经过多番调试与查找资料才明白了其中的细节 1等待命令执行结束用waitFor()其返回值就是命令的返回值 2如果出现程序执行被挂起没有任何反应的情况是由于没有读取命令子进程的正常输出流或错误输出流导致缓冲区被占满进程被锁住。这个时候需要把输出流中的内容给读出来。最好的做法是使用两个线程分别同时读取正常输出流和错误输出流。 3执行Windows平台上的命令时使用cmd.exe /C如cmd.exe /C dir。 4记得关闭命令子进程的输入流通过Process.getOutputStream().close()这样不会导致命令子进程被锁住。 1、Runtime.exec的用法 The class java.lang.Runtime features a static method called getRuntime(), which retrieves the current Java Runtime Environment. This is the only way to obtain a reference to the Runtime Object. With this reference you can run external programs by invoking the Runtime class’s exec() method. Developers often call this method to launch a browser for displaying a help page in HTML. There are four overloaded version of the exec() command: Public Process exec(String command); Public Process exec(String[] cmdArray); Public Process exec(String command, String []envp); Public Process exec(String [] cmdArray, String []envp); For each of these methods, a command—and possible and possibly a set of arguments—is passed to an operating system function call. This subsequently creates an operating system specific process(a running program )with a reference to a Process class returned to the Java VM. The Process is a abstract class ,because a specific subclass of Process exists for each operating system. You can pass three possible input params into to these methods: 1.a single string that represents both the program to execute and any args to the program. 2.an array of strings that separate the program from its argumen 3.an array of the environment variables. Pass the environment variables in the form namevalue. If you use the version of exec() with a sigle string for both the program and its arguments, note that the string is parsed using white space as the delimiter via the StringTokenizer class. The first pitfall relating to Runtime.exec() is the IllegalThreadStateException the prevalent first test of an API is to code its most obvious methods.To see the value the external process returns we use the exitValue() method on the Process class. In our first example, we will attempt to execute the Java compliere(javac.exe) 2、一个错误的程序示例 java 代码import java.util.*; import java.io.*; public class BadExecJavac {     public static void main(String args[])     {         try         {                        Runtime rt Runtime.getRuntime();             Process proc rt.exec(javac);             int exitVal proc.exitValue();             System.out.println(Process exitValue: exitVal);         } catch (Throwable t)           {             t.printStackTrace();           }     } } 运行结果如下 E:\classes\com\javaworld\jpitfalls\article2java BadExecJavac java.lang.IllegalThreadStateException: process has not exited          at java.lang.Win32Process.exitValue(Native Method)          at BadExecJavac.main(BadExecJavac.java:13) 这是因为当进程还没有结束的情况下调用exitValue方法会抛出IllegalThreadStateException.当然了我们会问为什吗这个方法不会等到进程结束在返回一个合理的值 在检查Process类的所有可用方法以后我们发现WairFor()是一个更合适的方法。事实上waitFor也会返回exit value。这意味着你不可以同时用exitvalue和waitfor而是只能选择一个。 当然了也有情况你要在waitfor之前用exitvalue方法就是你不想因为外部程序永远无法完成而一直等待下去。 因此为了避免这个陷阱我们要么捕获IllegalThreadStateException异常要么等待进程完成。我们相当然的以为可以用waitfor来等待程序的结束。代码如下 java 代码import java.util.*; import java.io.*; public class BadExecJavac2 {      public static void main(String args[])      {          try          {                          Runtime rt Runtime.getRuntime();              Process proc rt.exec(javac);              int exitVal proc.waitFor();              System.out.println(Process exitValue: exitVal);          } catch (Throwable t)            {              t.printStackTrace();            }      } } 这次在linux下面返回的结果是2,而在windows下面据说程序会挂起关于其原因我们可以在jdk文档中找到部分解释因为一些操作系统为标准的输入输出仅仅提供有限的缓冲区当不能正确的将信息写进输入流或者从输出流中获取信息时就会导致子进程的阻塞甚至死锁。 3、一个平庸的解决方案 现在我们就根据jdk文档来处理javac进程的输出当你不带任何参数运行javac时它会打印出一系列的有用的提示信息。而这些会被传送到stderr流中。我们可以写程序在其返回前获取这些信息。下面的代码提供了一个平庸的解决方案。 java 代码import java.util.*; import java.io.*; public class MediocreExecJavac {      public static void main(String args[])      {          try          {                          Runtime rt Runtime.getRuntime();              Process proc rt.exec(javac);              InputStream stderr proc.getErrorStream();              InputStreamReader isr new InputStreamReader(stderr);              BufferedReader br new BufferedReader(isr);              String line null;              System.out.println(ERROR);              while ( (line br.readLine()) ! null)                  System.out.println(line);              System.out.println(/ERROR);              int exitVal proc.waitFor();              System.out.println(Process exitValue: exitVal);          } catch (Throwable t)            {              t.printStackTrace();            }      } } 这次程序可以正确的输出了提示信息但是我们应该注意到其返回代码是2我们知道任何非0的返回代码都表示程序不正常。所以我们需要进一步的查找原因。对于win32而言是file not found很明显javac期望我们提供编译的文件。所以对于永远挂起的问题如果你运行的程序会有输出或者要求输出入时你需要处理输出和输入。 3、不要把命令当成一个可以执行的程序 很多新手把一些windows的命令当中可以独立运行的程序因此他们就陷入了Runtime的另一个陷阱如下面的例子所示 java 代码import java.util.*; import java.io.*; public class BadExecWinDir {      public static void main(String args[])      {          try          {                          Runtime rt Runtime.getRuntime();              Process proc rt.exec(dir);              InputStream stdin proc.getInputStream();              InputStreamReader isr new InputStreamReader(stdin);              BufferedReader br new BufferedReader(isr);              String line null;              System.out.println(OUTPUT);              while ( (line br.readLine()) ! null)                  System.out.println(line);              System.out.println(/OUTPUT);              int exitVal proc.waitFor();                          System.out.println(Process exitValue: exitVal);          } catch (Throwable t)            {              t.printStackTrace();            }      } } 据说在windows下面会抛出如下的异常 java.io.IOException: CreateProcess: dir error2          at java.lang.Win32Process.create(Native Method)          at java.lang.Win32Process.init(Unknown Source)          at java.lang.Runtime.execInternal(Native Method)          at java.lang.Runtime.exec(Unknown Source)          at java.lang.Runtime.exec(Unknown Source)          at java.lang.Runtime.exec(Unknown Source)          at java.lang.Runtime.exec(Unknown Source)          at BadExecWinDir.main(BadExecWinDir.java:12) 我在linux下面运行的结果是正确的。前面说了在win32下面2代表是文件没有找到而在这种情况下表明是dir.exe没有找到因为根本就没有这个文件他们都被封装到common.com win95或者cmd.exe中了。 下面我们列出一个正确的处理Process的输入输出流的方法。需要用一个线程类。 java 代码import java.util.*; import java.io.*; class StreamGobbler extends Thread {      InputStream is;      String type;     StreamGobbler(InputStream is, String type)      {          this.is is;          this.type type;      }           public void run()      {          try          {              InputStreamReader isr new InputStreamReader(is);              BufferedReader br new BufferedReader(isr);              String linenull;              while ( (line br.readLine()) ! null)                  System.out.println(type line);                  } catch (IOException ioe)                {                  ioe.printStackTrace();                 }      } } 用于专门的处理输入输出。 java 代码public class GoodWindowsExec {      public static void main(String args[])      {          if (args.length 1)          {              System.out.println(USAGE: java GoodWindowsExec cmd);              System.exit(1);          }                   try          {                          String osName System.getProperty(os.name );              String[] cmd new String[3];              if( osName.equals( Windows NT ) )              {                  cmd[0] cmd.exe ;                  cmd[1] /C ;                  cmd[2] args[0];              }              else if( osName.equals( Windows 95 ) )              {                  cmd[0] command.com ;                  cmd[1] /C ;                  cmd[2] args[0];              }                           Runtime rt Runtime.getRuntime();              System.out.println(Execing cmd[0] cmd[1]                                  cmd[2]);              Process proc rt.exec(cmd);              // any error message?              StreamGobbler errorGobbler new                  StreamGobbler(proc.getErrorStream(), ERROR);                                       // any output?              StreamGobbler outputGobbler new                  StreamGobbler(proc.getInputStream(), OUTPUT);                               // kick them off              errorGobbler.start();              outputGobbler.start();                                                   // any error???              int exitVal proc.waitFor();              System.out.println(ExitValue: exitVal);                  } catch (Throwable t)            {              t.printStackTrace();            }      } } 如果运行如下命令上面的代码会调用word程序 java GoodWindowExec “abc.doc” 也就是说文件类型如果window能够识别它就会调用对应的程序处理。 StreamGlobbler的最重要作用是他会清空所有的传递给他的inputstream这样不会造成Process阻塞或者死锁。 另外一种实现方式 java 代码package cmd;    import java.io.BufferedReader;  import java.io.InputStream;  import java.io.InputStreamReader;    class StreamDrainer implements Runnable {      private InputStream ins;        public StreamDrainer(InputStream ins) {          this.ins ins;      }        public void run() {          try {              BufferedReader reader new BufferedReader(                      new InputStreamReader(ins));              String line null;              while ((line reader.readLine()) ! null) {                  System.out.println(line);              }          } catch (Exception e) {              e.printStackTrace();          }      }    }    public class TestRunCmd {        public static void main(String[] args) {          String[] cmd new String[] { cmd.exe, /C, wmic process get name };          try {              Process process Runtime.getRuntime().exec(cmd);                            new Thread(new StreamDrainer(process.getInputStream())).start();              new Thread(new StreamDrainer(process.getErrorStream())).start();                            process.getOutputStream().close();                int exitValue process.waitFor();              System.out.println(返回值 exitValue);          } catch (Exception e) {              e.printStackTrace();          }        }    }  4、不要把exec当成命令行它不会重定向文件 如你在linux下面type ls abc.txt或者在window下面dirabc.txt 会把输出的结果通过管道重定向到文件中。但是exec不会。你必须自己写程序来处理。
http://www.ihoyoo.com/news/77401.html

相关文章:

  • 做什么网站赚钱最快营销型网站类型
  • 主流大型网站开发语言调查遵义做网站优化
  • 手机模板网站生成制作加强网站政务服务建设方案
  • 天津建设招标网站京东网上商城跟京东是一家吗
  • 安徽平台网站建设企业wordpress nginx 500错误
  • 甘肃酒泉建设银行网站海南省城乡与住房建设厅网站
  • 用wordpress仿站网站首页的尺寸做多大
  • 网站开发需要书籍宁波网络营销公司
  • 广州市专注网站建设品牌用discuz做的门户网站
  • 网站建设与管理量化考细则互动营销案例都有哪些
  • 肇东市建设局网站网站流量方案
  • 山东专业企业网站建设互联网c2c交易类网站详细策划书
  • 怎么开发自己的网站南宁在哪里推广网站
  • 好看网站做cpa建什么网站好
  • 南昌市会做网站有哪几家中装建设市值
  • 织梦建站教程下载wordpress 文章缩略图
  • 天津手机网站建设制作企业做网站有什么作用
  • 现在手机网站用什么做的客户端下载
  • 湖北建设执业资格注册中心网站西安哪里可以做公司网站
  • 网站架构图图做外贸什么网站比较好
  • 网站推广意识薄弱网站游戏网站建设
  • 深圳专业营销网站公司深入理解wordpress
  • 做电影ppt模板下载网站wordpress word图表
  • 邵阳网站建设怎么把网页做成app
  • 番禺做网站企业网站排名配色
  • 专业的企业网站优化公司网站开发后端有哪些
  • 柯林wap建站程序个人版贴图库外链图床wordpress插件
  • 建站技术服务360官方下载官网
  • 行情工具百度网站推广排名优化
  • 手机端网站欣赏wordpress 积分可见