java 子进程输出流_12.6 Java虚拟机读写其他进程的数据

一、回顾

回顾Java的Runtime类可以单独启动一个进程来运行操作系统的命令,如下程序所示:

package section6;

public class ExecTest

{

public static void main(String[] args)

throws Exception

{

//程序不能创建自己的Runtime实例,但是可以通过getRuntime()

//获取与之相关联的Runtime实例

var rt=Runtime.getRuntime();

//运行记事本

rt.exec("notepad.exe");

}

}

二、Runtime对象的exec()产生Process对象的

使用Runtime对象的exec()方法可以运行平台上的其他程序,该方法产生一个Process对象,Process对象代表由该Java程序启动子进程。Process对象提供了如下三个方法,用于让程序和其他子进程之间进行通信。

★InputStream getErrorStream():获取子进程的错误流。

★InputStream getInputStream():获取子进程的输入流。

★OutputStream getOutputStream():获取子进程的输出流。

注意:如果试图让子进程读取程序中的数据,那么应该使用输出流。要站在Java角度来看问题,子程序读取Java程序的数据,就是让Java程序把数据输出到子进程中(就像把数据输出到文件中一样,只是由子进程节点代替了文件节点),所以应该使用输出流。

2.1 获取子程序的输出流作为本程序的输入流

下程序示范了读取其他进程的输出信息:

package section6;

import java.io.BufferedReader;

import java.io.InputStreamReader;

public class ReadFromProcess

{

public static void main(String[] args)

throws Exception

{

//运行javac命令,返回该命令的子进程

Process p=Runtime.getRuntime().exec("javac");

try(

//以p进程的错误输出流创建BufferedRead对象

//这个错误流对p进程是输出流,对于本程序是输入流

//1、首先将这个错误流转换为字符流

var cs=new InputStreamReader(p.getInputStream());

//2、转换流转化为BufferedReader流

var br=new BufferedReader(cs)

)

{

String buff=null;

while((buff=br.readLine())!=null)

{

System.out.println(buff);

}

}

}

}

上面程序使用Runtime启动了javac程序,获取了运行该程序的子进程;然后以p进程的错误输入流创建了bufferedReader,这个输入流的流向如图所示:

d51044fe4a51ef2a50ea553f4b14dd7c.png

注:以前版本的javac进程的错误输入流要通过getErrorStream()方法获取,现在改为getInputStream()方法获取。

下图所示的数据流对p进程(javac进程)而言,它是输出流;但对本程序而言,它是输入流——衡量输入输出流总是站在本程序所在的内存角度,所以数据流应该是输入流。

304427007e73b45c6d63dd500120e666.png

2.2 本程序的输出流作为子进程的输入流

可以通过Process的getOutputStream()方法获得项进程输入数据的流(该流对Java程序是输出流,对子进程则是输入流),下面程序实现了在Java程序中启动Javaxu

import java.io.*;

import java.util.*;

public class WriteToProcessplus

{

public static void main(String[] args)

throws IOException

{

// 运行java ReadStandard命令,返回运行该命令的子进程

Process p = Runtime.getRuntime().exec("java ReadStandardplus");

try (

// 以p进程的输出流创建PrintStream对象

// 这个输出流对本程序是输出流,对p进程则是输入流

var ps = new PrintStream(p.getOutputStream()))

{

// 向ReadStandard程序写入内容,这些内容将被ReadStandard读取

ps.println("普通字符串");

ps.println(new WriteToProcessplus());

}

}

}

// 定义一个ReadStandard类,该类可以接受标准输入,

// 并将标准输入写入out.txt文件。

class ReadStandardplus

{

public static void main(String[] args)

{

try (

// 使用System.in创建Scanner对象,用于获取标准输入

var sc = new Scanner(System.in);

var ps = new PrintStream(new FileOutputStream("out.txt")))

{

// 增加下面一行将只把回车作为分隔符

sc.useDelimiter("\n");

// 判断是否还有下一个输入项

while (sc.hasNext())

{

// 输出输入项

ps.println("键盘输入的内容是:" + sc.next());

}

}

catch (IOException ioe)

{

ioe.printStackTrace();

}

}

}

在WriteToProcess中使用Runtime的exec()方法来运行java ReadStandard命令,该命令将运行ReadStandard类,并返回该程序的子进程。var ps = new PrintStream(p.getOutputStream())获取子进程的p的输出流——该输出流对于p进程是输入流,对于本程序是输出流。本程序通过该输出流向进程p中输入数据。

0a4b4acb8c5d8efd88ebe4c18563b441.png

运行后将看到一个out.txt文档,内容为:

df37de40e876e05c56cf211c2e0b1387.png

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值