• 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,这个输入流的流向如图所示:

    注:以前版本的javac进程的错误输入流要通过getErrorStream()方法获取,现在改为getInputStream()方法获取。
    下图所示的数据流对p进程(javac进程)而言,它是输出流;但对本程序而言,它是输入流——衡量输入输出流总是站在本程序所在的内存角度,所以数据流应该是输入流。

    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("
    ");
    			// 判断是否还有下一个输入项
    			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中输入数据。

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

  • 相关阅读:
    单元测试的那点事儿
    centos 下载为firefox安装flash插件
    ubuntu lamp(apache+mysql+php) 环境搭建及相关扩展更新
    PHP源代码数组统计count分析
    fgetcsv函数的“陷阱”
    安装phpunit出现could not extract the package.xml file
    Centos Nginx + Svbversion配置安装
    双系统XP和ubuntu,升级ubuntu出现no such device grub rescue
    centos5 源码安装Nginx + mysql + apache + php
    再谈fgetcsv之在ubuntu10.10下不能解析中文的问题
  • 原文地址:https://www.cnblogs.com/weststar/p/12814544.html
Copyright © 2020-2023  润新知