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

StreamGobbler的详细解释

阅读更多
这是摘自《More Java pitfalls 中文版》上的例子。

先请编译和运行下面程序:
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(); 
        } 
    } 
}   



我们知道javac命令,当不带参数运行javac 程序时,它将输出帮助说明,为什么上面程序不产生任何输出并挂起,永不完成呢?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(); 
        } 
    } 
} 




下面是正确的输出:

D:\java>java   MediocreExecJavac
<ERROR>
Usage: javac <options> <source files>
where possible options include:
  -g                         Generate all debugging info
  -g:none                    Generate no debugging info
  -g:{lines,vars,source}     Generate only some debugging info
  -nowarn                    Generate no warnings
  -verbose                   Output messages about what the compiler is doing
  -deprecation               Output source locations where deprecated APIs are used
  -classpath <path>          Specify where to find user class files
  -cp <path>                 Specify where to find user class files
  -sourcepath <path>         Specify where to find input source files
  -bootclasspath <path>      Override location of bootstrap class files
  -extdirs <dirs>            Override location of installed extensions
  -endorseddirs <dirs>       Override location of endorsed standards path
  -d <directory>             Specify where to place generated class files
  -encoding <encoding>       Specify character encoding used by source files
  -source <release>          Provide source compatibility with specified release

  -target <release>          Generate class files for specific VM version
  -version                   Version information
  -help                      Print a synopsis of standard options
  -X                         Print a synopsis of nonstandard options
  -J<flag>                   Pass <flag> directly to the runtime system

</ERROR>
Process exitValue: 2

D:\java>


下面是一个更一般的程序,它用两个线程同步清空标准错误流和标准输出流,并能根据你所使用的windows操作系统选择windows命令解释器command.com或cmd.exe,然后执行你提供的命令。


import java.util.*; 
import java.io.*; 

class StreamGobbler extends Thread 
{ 
    InputStream is; 
    String type;  //输出流的类型ERROR或OUTPUT 
     
    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 line=null; 
            while ( (line = br.readLine()) != null) 
            { 
                System.out.println(type + ">" + line); 
                System.out.flush(); 
            } 
            } catch (IOException ioe) 
              { 
                ioe.printStackTrace();   
              } 
    } 
} 

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" ); 
            System.out.println("osName: " + osName); 
            String[] cmd = new String[3]; 

            if(osName.equals("Windows XP") ||osName.equals("Windows 2000")) 
            { 
                cmd[0] = "cmd.exe" ; 
                cmd[1] = "/C" ; 
                cmd[2] = args[0]; 
            } 
            else if( osName.equals( "Windows 98" ) ) 
            { 
                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(); 
        } 
    } 
} 





下面是一个测试结果:

D:\java>java  GoodWindowsExec "copy Test.java Test1.java"
osName: Windows XP
Execing cmd.exe /C copy Test.java Test1.java
OUTPUT>已复制         1 个文件。
ExitValue: 0

D:\java>

下面的测试都能通过(windows xp+jdk1.5)

D:\java>java   GoodWindowsExec dir

D:\java>java   GoodWindowsExec Test.java

D:\java>java   GoodWindowsExec regedit.exe

D:\java>java   GoodWindowsExec NOTEPAD.EXE

D:\java>java   GoodWindowsExec first.ppt

D:\java>java   GoodWindowsExec second.doc


以上的意思是说如果不使用StreamGobbler把inputstream清空的话,就会造成进程被堵死,从而导致waitFor()一直等下去,永远结束不了.所以StreamGobbler作为单独的线程会自动清理inputstream防止他被堵住
分享到:
评论

相关推荐

    StreamGobbler.java

    StreamGobbler.java

    org.apache.commons.net.ftp*实现FTP下载

    利用org.apache.commons.net.ftp.*实现FTP批量下载,包括子目录文件

    ssh协议依赖jar包:ganymed-ssh2-build

    ganymed-ssh2-build ssh2 ch.ethz.ssh2.Connection ch.ethz.ssh2.SCPClient

    ganymed-ssh2-build210.jar java远程访问linux服务器操作、上传下载文件

    import ch.ethz.ssh2.StreamGobbler; import common.Logger; import org.apache.commons.lang.StringUtils; import java.io.*; import java.util.logging.Level; /** * SCP远程访问Linux服务器读取文件 * User: ...

    年终工作总结汇报PPTqytp.pptx

    年终工作总结汇报PPTqytp.pptx

    setuptools-32.1.1-py2.py3-none-any.whl

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    基于java的聊天系统的设计于实现.zip

    基于java的聊天系统的设计于实现

    罗兰贝格_xx事业部制建议书gltp.pptx

    罗兰贝格_xx事业部制建议书gltp.pptx

    setuptools-18.6-py2.py3-none-any.whl

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    基于luatos的W801单片机载具开环控制程序.zip

    基于单片机的系统

    企业管理与人力资源管理咨询项目gltp.pptx

    企业管理与人力资源管理咨询项目gltp.pptx

    基于JSP民宿预订网站信息管理平台源码.zip

    这个是一个JSP民宿预订网站信息管理平台,管理员角色包含以下功能:管理员登录,用户管理,会员管理,民宿信息管理,新闻管理,留言管理等功能。用户角色包含以下功能:用户登录与注册,查看网站新闻,查看民宿信息,查看留言板,修改个人信息,提交订单,查看我的订单等功能。 本项目实现的最终作用是基于JSP民宿预订网站信息管理平台 分为2个角色 第1个角色为管理员角色,实现了如下功能: - 会员管理 - 新闻管理 - 民宿信息管理 - 用户管理 - 留言管理 - 管理员登录 第2个角色为用户角色,实现了如下功能: - 修改个人信息 - 提交订单 - 查看我的订单 - 查看民宿信息 - 查看留言板 - 查看网站新闻 - 用户登录与注册

    数字通信原理(第二版)课后答案-主编:周冬梅

    数字通信原理(第二版)课后答案

    setuptools-34.0.2.zip

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    学生实验课程-纯c语言迷宫源码

    学生实验课程-纯c语言迷宫源码

    基于JSP网上二手交易商城源码.zip

    这个是一个JSP网上二手交易商城,管理员角色包含以下功能:管理员登录,用户管理,商品分类管理,商品管理,订单管理,留言管理,新闻公告管理等功能。用户角色包含以下功能:查看首页,查看商品,用户登录和注册,加入购物车,查看订单,留言等功能。

    setuptools-8.0.3-py2.py3-none-any.whl

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    setuptools-42.0.0-py2.py3-none-any.whl

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    什么是c语言文件读写操作代码以及学习c语言文件读写操作代码的意义

    c语言文件读写操作代码

    setuptools-38.0.0-py2.py3-none-any.whl

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

Global site tag (gtag.js) - Google Analytics