- 浏览: 261750 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
申1987:
收藏
Java解析XML文件 -
wangyu2010302660001:
发布成文本Service后,那个testclass就load不 ...
使用URLClassLoader动态加载类 -
joe_zhpf:
thanks 终于理解了..
android touch mode -
wander312:
嗯, 我试的OK.
android findViewById 返回null的问题 -
javetu_7:
你说的也不对,我试了,还是NULL
android findViewById 返回null的问题
这是摘自《More Java pitfalls 中文版》上的例子。
先请编译和运行下面程序:
我们知道javac命令,当不带参数运行javac 程序时,它将输出帮助说明,为什么上面程序不产生任何输出并挂起,永不完成呢?java文档上说,由于有些本地平台为标准输入和输出流所提供的缓冲区大小有限,如果不能及时写入子进程的输入流或者读取子进程的输出流,可能导致子进程阻塞,甚至陷入死锁。所以,上面的程序应改写为:
下面是正确的输出:
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,然后执行你提供的命令。
下面是一个测试结果:
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防止他被堵住
先请编译和运行下面程序:
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防止他被堵住
发表评论
-
区别在于内存分配的方式,allocate分配的内存在jvm管理范围内,directAllocate分配的内存则不是由jvm管理,可以理解成是类似 C++那种分配
2010-05-25 11:15 1580区别在于内存分配的方式,allocate分配的内存在jvm管理 ... -
java中ArrayList 、LinkList区别
2010-05-25 11:02 165721.ArrayList是实现了基于动态数组的数据结 ... -
谈谈Unicode编码,简要解释UCS、UTF、BMP、BOM等名词
2010-05-20 15:24 1184这是一篇程序员写 ... -
HashCode的作用
2010-05-18 14:09 5291首先,想要明白hashCode ... -
hashTable与HashMap区别
2010-05-07 09:50 1597HashTable的应用非常广泛, HashMap ... -
java String详解
2010-01-15 11:11 2722Java字符串类(java.lang.String)是Jav ... -
java 读xml
2009-12-25 16:05 895DocumentBuilderFactory factory ... -
抽象类实现接口,可以不实现其中的抽象方法
2009-12-03 13:20 2003抽象类实现接口,可以不实现其中的抽象方法,而将抽象方法的实现交 ... -
linux命令grep
2009-07-08 11:24 1459grep "key" xxx.log时输出 ... -
子类覆盖问题的解释
2009-07-07 16:31 1051如果子类没有重写父类的方法,调用父类的方法的时候,实际上是去父 ... -
关于字符集转换的本质问题。
2009-03-13 15:36 1491UTF-8 UTF-16BE UTF-16LE GB2312 ... -
java.lang.class类入门的介绍
2008-10-17 15:05 1479前言:Java的类库日益庞大,所包含的类和接口也不计其数。但其 ... -
内部类的介绍
2008-10-14 10:52 968提起Java内部类(Inner Class)可能很多人不太熟悉 ... -
java.io中的设计模式
2008-08-19 14:18 1587我想任何一本介绍模式的书在讲到Decorator模式的 ... -
使用Graphics2D画虚线和设置线的宽度
2008-07-31 15:50 11784public void paint(Graphics ... -
java变量基础
2008-07-30 10:35 1315变量 变量是指? 变量是存放 ... -
reader和stream的区别
2008-07-24 10:47 3068java.io.Reader 和 java.io.InputS ... -
111
2008-07-10 20:01 902hang out with: spend time with -
多线程的一些问题
2008-07-08 14:35 1088Java的线程编程非常简单。但有时会看到一些关于线程的错误用 ... -
Javax.comm串口通讯类简介
2008-07-08 13:33 4259Javax.comm简介 Javax.comm是Sun ...
相关推荐
StreamGobbler.java
利用org.apache.commons.net.ftp.*实现FTP批量下载,包括子目录文件
StreamGobbler errorGobbler = new StreamGobbler(errorStream, "ERROR"); errorGobbler.start(); ``` 3. **设置环境变量和工作目录**:通过`ProcessBuilder`的`environment()`和`directory()`方法设置必要的...
在IT行业中,PDF(Portable Document Format)是一种广泛用于存储和分发文档的格式,而HTML(HyperText Markup Language)则是互联网上网页的标准内容结构语言。... ...Java中有很多库可以帮助我们完成这项任务,如PDFBox...
下面将详细介绍Java代码执行shell命令的实现方法。 环境准备 在执行shell命令之前,需要获取JVM底层操作系统的信息,并定义通用消费流的类。为了获取操作系统的信息,可以使用`System.getProperty("os.name")`方法...
根据给定的信息,本文将详细解释如何通过Java应用程序实现对Linux服务器的远程登录,并执行相应的命令。本案例中,我们采用的是Ganymed SSH2库来实现这一功能。 ### 一、Ganymed SSH2 库简介 Ganymed SSH2 是一个...
`RunScript.java`和`StreamGobbler.java`这两个文件可能就是用来实现这个功能的。 `RunScript.java`很可能是主类,它包含了一个方法来判断当前运行的操作系统,并根据系统类型来执行相应的脚本。在Windows中,...
StreamGobbler outputGobbler = new StreamGobbler(process.getInputStream(), "Output"); errorGobbler.start(); outputGobbler.start(); // ... } ``` `Runtime.exec()`方法有几点需要注意: 1. **确保在...
下面我们将详细讲解如何操作。 首先,我们创建一个名为`jv_run_extpro`的Java源代码,其主要目的是通过`Runtime.getRuntime().exec(cmd)`方法执行系统命令。在这个Java类中,定义了一个`run`方法,该方法接收一个...
SSH(Secure Shell)协议是一种网络协议,用于在不安全的网络上提供安全的远程登录和其他服务。在Java环境中,开发人员通常使用库来实现SSH功能,其中一个常用的库就是Ganymed SSH-2。这个库名为ganymed-ssh2-build...
本文将详细介绍如何使用Java编程语言来启动和停止Appium服务器,这对于自动化测试流程的管理和控制至关重要。 首先,我们需要理解Appium的基本概念。Appium是一个基于WebDriver协议的自动化测试工具,它支持iOS、...
- `-v`:详细模式,显示执行的详细过程。 - `-c`:启用压缩。 - `-i`:指定私钥文件用于身份验证。 3. **基本操作示例**: - **从本地到远程**: ``` scp localfile user@remotehost:remotedir/ scp -r ...
因此,修改后的代码在执行bat命令时,不仅创建了bat进程,还同时启动了两个`StreamGobbler`线程,分别处理错误流和标准输出流,确保bat命令的输出能够被及时消费,从而避免了阻塞问题。 总的来说,解决Java执行bat...
- `StreamGobbler.java`:可能是用来处理输入流的类,可能包含从输入流中读取数据并进行编码转换的功能。 - `BufferedStream01.java`:可能实现了使用缓冲流进行文件读写的例子,可能涉及到字符编码转换。 - `...
下面我们将详细介绍Java应用程序远程登录Linux并执行命令的实现原理和实践。 _ssh协议和Java实现_ SSH(Secure Shell)是一种安全的远程登录协议,用于在网络上进行加密的连接和通信。Java可以通过使用SSH客户端库...
- 读取命令输出,通常使用 `StreamGobbler` 类来读取标准输出流和错误输出流。 ### 2. FTP 文件传输 #### 2.1 FTP 协议简介 FTP(File Transfer Protocol)是一种用于在网络上进行文件传输的标准协议。它支持...
2. `StreamGobbler.java`:这个名字暗示这可能是一个用于处理I/O流的辅助类,特别是处理命令行进程的输出流。在PDF转HTML过程中,如果使用了命令行工具,那么这个类可能用来捕获并处理子进程的输出,例如标准输出和...
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: ...
InputStream stdout = new StreamGobbler(session.getStdout()); BufferedReader br = new BufferedReader(new InputStreamReader(stdout)); ``` 五、关闭Session和Connection 最后,关闭Session和Connection: `...