- 浏览: 380329 次
- 性别:
- 来自: 上海
文章分类
- 全部博客 (215)
- ubuntu (27)
- 虚拟机 (13)
- 数据库 (29)
- JAVA (40)
- 搜索 (23)
- 开发工具 (2)
- 产品 (2)
- 工具 (1)
- 应用服务器 (5)
- linux (17)
- log (1)
- 多线程 (3)
- 异常 (1)
- shell (6)
- 12306 ;互联网 (1)
- 持续集成&Hudson (4)
- js (1)
- JAVA OR-Map (1)
- 漏洞 (1)
- svn (1)
- MAVEN (3)
- 架构 (1)
- windows (1)
- json (1)
- web (3)
- jenkins (2)
- iptables (2)
- JAVA ssh (0)
- 项目管理 (1)
- tomcat (1)
- 安全 (1)
- 数据库 mysql (1)
- 性能 (1)
最新评论
-
sbwfgihc:
怎么用的啊,
<转>mysql 树查询语句 -
panghaoyu:
实现一个智能提示功能需要ajax、数据库、jsp/php、算法 ...
<转>Solr Suggest实现搜索智能提示 -
songsove:
请问您qq多少
solr 对拼音搜索和拼音首字母搜索的支持 -
panghaoyu:
实现一个智能提示功能需要ajax、数据库、jsp/php、算法 ...
<转>Solr Suggest实现搜索智能提示 -
norain1988:
这样就可以实现相关搜索了吗
solr 百度相关搜索类似功能的实现
http://bbs.csdn.net/topics/110150995
http://blog.csdn.net/jason20075563/article/details/6066563
http://www.cnblogs.com/yejg1212/archive/2013/06/02/3114242.html
创建进程的方法可能无法针对某些本机平台上的特定进程很好地工作,比如,本机窗口进程,守护进程,Microsoft Windows 上的 Win16/DOS 进程,或者 shell 脚本。创建的子进程没有自己的终端或控制台。它的所有标准 io(即 stdin,stdout,stderr)操作都将通过三个流 (getOutputStream(),getInputStream(),getErrorStream()) 重定向到父进程。父进程使用这些流来提供到子进程的输入和获得从子进程的输出。因为有些本机平台仅针对标准输入和输出流提供有限的缓冲区大小,如果读写子进程的输出流或输入流迅速出现失败,则可能导致子进程阻塞,甚至产生死锁。
Java调用其他程序时waitFor()阻塞
前段时间在工作中遇到这样一个问题,java代码中调用一个bat程序,在linux下执行完好,但是换到windows下就一直挂在那里不动了~
代码如下:
复制代码
public class CMDTest {
public static void main(String[] args) {
Process p = null;
try {
p = Runtime.getRuntime().exec("c:\\test.bat");
p.waitFor();
System.out.println(p.exitValue());
System.out.println("over");
} catch (Exception e) {
e.printStackTrace();
}
}
}
复制代码
其中,test.bat里就是一些命令操作,在这里就写一个简单的ping命令。
ping www.baidu.com
上面的代码运行之后,等了半天都没反应。Process的api中有如下说明:
复制代码
ProcessBuilder.start() 和 Runtime.exec 方法创建一个本机进程,并返回 Process 子类的一个实例,该实例可用来控制进程并获得相关信息。Process 类提供了执行从进程输入、执行输出到进程、等待进程完成、检查进程的退出状态以及销毁(杀掉)进程的方法。
创建进程的方法可能无法针对某些本机平台上的特定进程很好地工作,比如,本机窗口进程,守护进程,Microsoft Windows 上的 Win16/DOS 进程,或者 shell 脚本。
创建的子进程没有自己的终端或控制台。它的所有标准 io(即 stdin、stdout 和 stderr)操作都将通过三个流 (getOutputStream()、getInputStream() 和 getErrorStream()) 重定向到父进程。父进程使用这些流来提供到子进程的输入和获得从子进程的输出。
因为有些本机平台仅针对标准输入和输出流提供有限的缓冲区大小,如果读写子进程的输出流或输入流迅速出现失败,则可能导致子进程阻塞,甚至产生死锁。
复制代码
也就是说:如果程序不断在向标准输出流和标准错误流写数据,而JVM不读取的话,当缓冲区满之后将无法继续写入数据,最终造成阻塞在waitFor()这里。
这就是问题所在!之后我查了下网上的解决办法,多数是创建两个线程在waitFor()命令之前读出窗口的标准输出缓冲区和标准错误流的内容。
按照这个思路,我写了如下util方法
复制代码
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
public class CommandUtil {
// 保存进程的输入流信息
private List<String> stdoutList = new ArrayList<String>();
// 保存进程的错误流信息
private List<String> erroroutList = new ArrayList<String>();
public void executeCommand(String command) {
// 先清空
stdoutList.clear();
erroroutList.clear();
Process p = null;
try {
p = Runtime.getRuntime().exec(command);
// 创建2个线程,分别读取输入流缓冲区和错误流缓冲区
ThreadUtil stdoutUtil = new ThreadUtil(p.getInputStream(), stdoutList);
ThreadUtil erroroutUtil = new ThreadUtil(p.getErrorStream(), erroroutList);
//启动线程读取缓冲区数据
stdoutUtil.start();
erroroutUtil.start();
p.waitFor();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public List<String> getStdoutList() {
return stdoutList;
}
public List<String> getErroroutList() {
return erroroutList;
}
}
class ThreadUtil implements Runnable {
// 设置读取的字符编码
private String character = "GB2312";
private List<String> list;
private InputStream inputStream;
public ThreadUtil(InputStream inputStream, List<String> list) {
this.inputStream = inputStream;
this.list = list;
}
public void start() {
Thread thread = new Thread(this);
thread.setDaemon(true);//将其设置为守护线程
thread.start();
}
public void run() {
BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(inputStream, character));
String line = null;
while ((line = br.readLine()) != null) {
if (line != null) {
list.add(line);
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
//释放资源
inputStream.close();
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
复制代码
再整个方法测试下:
复制代码
import java.util.List;
public class TestMain {
public static void main(String[] args) {
CommandUtil util = new CommandUtil();
util.executeCommand("c:\\test.bat");
printList(util.getStdoutList());
System.out.println("--------------------");
printList(util.getErroroutList());
}
public static void printList(List<String> list){
for (String string : list) {
System.out.println(string);
}
}
}
复制代码
这样一来,问题确实解决了,再也不会出现阻塞了~
http://blog.csdn.net/jason20075563/article/details/6066563
http://www.cnblogs.com/yejg1212/archive/2013/06/02/3114242.html
创建进程的方法可能无法针对某些本机平台上的特定进程很好地工作,比如,本机窗口进程,守护进程,Microsoft Windows 上的 Win16/DOS 进程,或者 shell 脚本。创建的子进程没有自己的终端或控制台。它的所有标准 io(即 stdin,stdout,stderr)操作都将通过三个流 (getOutputStream(),getInputStream(),getErrorStream()) 重定向到父进程。父进程使用这些流来提供到子进程的输入和获得从子进程的输出。因为有些本机平台仅针对标准输入和输出流提供有限的缓冲区大小,如果读写子进程的输出流或输入流迅速出现失败,则可能导致子进程阻塞,甚至产生死锁。
Java调用其他程序时waitFor()阻塞
前段时间在工作中遇到这样一个问题,java代码中调用一个bat程序,在linux下执行完好,但是换到windows下就一直挂在那里不动了~
代码如下:
复制代码
public class CMDTest {
public static void main(String[] args) {
Process p = null;
try {
p = Runtime.getRuntime().exec("c:\\test.bat");
p.waitFor();
System.out.println(p.exitValue());
System.out.println("over");
} catch (Exception e) {
e.printStackTrace();
}
}
}
复制代码
其中,test.bat里就是一些命令操作,在这里就写一个简单的ping命令。
ping www.baidu.com
上面的代码运行之后,等了半天都没反应。Process的api中有如下说明:
复制代码
ProcessBuilder.start() 和 Runtime.exec 方法创建一个本机进程,并返回 Process 子类的一个实例,该实例可用来控制进程并获得相关信息。Process 类提供了执行从进程输入、执行输出到进程、等待进程完成、检查进程的退出状态以及销毁(杀掉)进程的方法。
创建进程的方法可能无法针对某些本机平台上的特定进程很好地工作,比如,本机窗口进程,守护进程,Microsoft Windows 上的 Win16/DOS 进程,或者 shell 脚本。
创建的子进程没有自己的终端或控制台。它的所有标准 io(即 stdin、stdout 和 stderr)操作都将通过三个流 (getOutputStream()、getInputStream() 和 getErrorStream()) 重定向到父进程。父进程使用这些流来提供到子进程的输入和获得从子进程的输出。
因为有些本机平台仅针对标准输入和输出流提供有限的缓冲区大小,如果读写子进程的输出流或输入流迅速出现失败,则可能导致子进程阻塞,甚至产生死锁。
复制代码
也就是说:如果程序不断在向标准输出流和标准错误流写数据,而JVM不读取的话,当缓冲区满之后将无法继续写入数据,最终造成阻塞在waitFor()这里。
这就是问题所在!之后我查了下网上的解决办法,多数是创建两个线程在waitFor()命令之前读出窗口的标准输出缓冲区和标准错误流的内容。
按照这个思路,我写了如下util方法
复制代码
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
public class CommandUtil {
// 保存进程的输入流信息
private List<String> stdoutList = new ArrayList<String>();
// 保存进程的错误流信息
private List<String> erroroutList = new ArrayList<String>();
public void executeCommand(String command) {
// 先清空
stdoutList.clear();
erroroutList.clear();
Process p = null;
try {
p = Runtime.getRuntime().exec(command);
// 创建2个线程,分别读取输入流缓冲区和错误流缓冲区
ThreadUtil stdoutUtil = new ThreadUtil(p.getInputStream(), stdoutList);
ThreadUtil erroroutUtil = new ThreadUtil(p.getErrorStream(), erroroutList);
//启动线程读取缓冲区数据
stdoutUtil.start();
erroroutUtil.start();
p.waitFor();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public List<String> getStdoutList() {
return stdoutList;
}
public List<String> getErroroutList() {
return erroroutList;
}
}
class ThreadUtil implements Runnable {
// 设置读取的字符编码
private String character = "GB2312";
private List<String> list;
private InputStream inputStream;
public ThreadUtil(InputStream inputStream, List<String> list) {
this.inputStream = inputStream;
this.list = list;
}
public void start() {
Thread thread = new Thread(this);
thread.setDaemon(true);//将其设置为守护线程
thread.start();
}
public void run() {
BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(inputStream, character));
String line = null;
while ((line = br.readLine()) != null) {
if (line != null) {
list.add(line);
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
//释放资源
inputStream.close();
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
复制代码
再整个方法测试下:
复制代码
import java.util.List;
public class TestMain {
public static void main(String[] args) {
CommandUtil util = new CommandUtil();
util.executeCommand("c:\\test.bat");
printList(util.getStdoutList());
System.out.println("--------------------");
printList(util.getErroroutList());
}
public static void printList(List<String> list){
for (String string : list) {
System.out.println(string);
}
}
}
复制代码
这样一来,问题确实解决了,再也不会出现阻塞了~
发表评论
-
<转>Hessian入门(与Spring集成)
2015-01-20 10:31 4363原链接:http://blog.csdn.net/chenwe ... -
<转>如何编程实现 2 + 2 = 5?
2014-10-16 11:00 771原链接:http://codeway.co/%E5%A6%82 ... -
<转>利用位操作来进行状态操作
2014-07-15 11:00 666print?<SPAN style="BACK ... -
java命令
2014-04-23 17:17 777jps -v 查看所有的jvm进程,包括进程ID,进程启动的路 ... -
<转>给Tomcat,Apache配置gzip压缩(HTTP压缩)功能
2014-03-28 14:14 418原链接:http://www.blogjava.net/juh ... -
<转>JVM调优总结 -Xms -Xmx -Xmn -Xss
2014-01-21 21:21 838原链接:http://unixboy.iteye.com/bl ... -
<转>Eclipse 常用设置
2013-12-23 16:26 667原链:http://blog.csdn.net/appleca ... -
tomcat各版本信息
2013-12-23 10:02 754Apache官方对各版本的解释:http://tomcat ... -
<转> 如何获取用户的真实IP
2013-12-23 09:40 654问题引出: 在JSP里,获取客户端的IP地址的方法是:re ... -
从SVN导出指定版本号之间修改的文件
2013-12-20 16:55 516转:http://www.kuqin.com/manageto ... -
用JAVA调用ssh命令
2013-12-09 15:21 1890原链:http://blog.csdn.net/f ... -
java有效的IP正则表达式
2013-11-06 20:46 824public static boolean isboolIp ... -
<转>JSCH 如何实现在远程机器上执行linux命令
2013-08-23 09:34 1378原链:http://blog.csdn.net/hongbin ... -
<转>session 之session混乱解决方法
2013-08-07 21:23 1737转:http://blog.csdn.net/wmj2003/ ... -
Java JSON技术框架选型与实例
2013-08-05 15:12 764JSON JSON英文全称为JavaScript Obje ... -
JVM内存结构系列:HotSpot内存结构最清晰
2013-07-29 11:37 763SUN的jvm内存池被划分为以下几个部分:Eden Spa ... -
<转>探究两大Java内存溢出类型
2013-07-29 10:31 718你知道如何解决Java内 ... -
<转>list,set,map,数组间的相互转换
2013-07-25 12:30 939原链:http://teamojiao.iteye.com/ ... -
Eclipse调试Bug的七种常用技巧
2013-07-04 10:24 795记得刚刚毕业的时候,自己连断点也不会打,当时还在用JCre ... -
Log4j 日志级别
2013-04-19 11:10 1038级别顺序(低到高): DEBUG < INFO < ...
相关推荐
Java中OutputStream类数据操作方法.pdf 学习资料 复习资料 教学资源
OutputStream os = new FileOutputStream(file2);// 打开文件 os.write(cont); os.close();// 关闭文件 } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) ...
当你还是一个java初学者的时候,是不是还在为你没有一个好的源代码模仿去学习而烦恼,这个代码很容易看懂,对你学习很有帮助
InputStream与OutputStream及File间互转
Xmodem和Ymodem 传输协议JAVA实现
FileWriter、FileReader、CharArrayReader、CharArrayWriter、CharSequence、...OutputStream、ByteArrayOutputStream、SequenceInputStream、BufferedOutputStream、BufferedInputStream、PipedReader、PipedWriter、...
NULL 博文链接:https://anminer.iteye.com/blog/845067
关于InputStream和OutputStream关于InputStream和OutputStream关于InputStream和OutputStream关于InputStream和OutputStream
NULL 博文链接:https://shihuan830619.iteye.com/blog/2094068
import java.io.OutputStream; import java.util.HashMap; import java.util.Map; import org.apache.poi.hssf.usermodel.HSSFCell; import org.apache.poi.hssf.usermodel.HSSFCellStyle; import org.apache.poi....
import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.net.Socket; import java.util.Scanner; import login.Choice; import org.dom4j.DocumentException;...
1.3.6 缓冲区流 1.3.7 原始型数据流 1.3.8 对象流 1.3.9 字符流 InputStreamReader/OutputStreamWriter 1.3.10 随机存取文件 RandomAccessFile 1.3.11 小结 1.4 java中的一些常用词汇 1.5 J2SE学习中的30个基本概念 ...
文件缓冲区 概述 该软件包实现了FileBuffer类,该类可以用java.io.OutputStream写入并通过java.io.InputStream读取。 写入会进入缓冲区的尾部,而读取会从头部开始。 该实现可确保阅读不会超过写作,从而保留了java....
1 Java程序源代码须先通过 编译器 产生Java虚拟机器的机器码 bytecode 再经过解释器将其转成实际使用的机器和操作系统上的机器码执行 2 类中定义有 abstract 方法 此类一定要声明为抽象类 3 在java语言定义中 ...
发送网络字节流 pack stream php
缓冲区(Buffer)通道(Channel) 示例:文件拷贝案例 BIO 和 NIO 拷贝文件的区别操作系统的零拷贝 选择器(Selectors) 选择键(SelectionKey) 示例:简易的客户端服务器通信 集合 集合框架总览 -、Iterator Iterable ...
Java 网络编程 说明: 网络编程,分为两种一种是TCP、另一种是UDP方式。我们分别写一下TCP、UDP端的Server和Client简单演示代码。 TCP: Sever import java.io.DataInputStream; import java.io.IOException; ...
java io 详解 inputstream outputstream 装饰模式
NULL 博文链接:https://312256159-qq-com.iteye.com/blog/1686213
- 缓冲区(Buffer) - 通道(Channel) - 示例:文件拷贝案例 - BIO 和 NIO 拷贝文件的区别 - 操作系统的零拷贝 - 选择器(Selectors) - 选择键(SelectionKey) - 示例:简易的客户端服务器通信 - 总结 ...