美文网首页
IO输入输出

IO输入输出

作者: 代码界的扫地僧 | 来源:发表于2017-09-07 17:19 被阅读11次

    介绍

    IO 实际就是输入流IN 输出 OUT
    输出流分stderr(标准错误输出) 和stdout(标准输出),c语言里 对应的就是全局对象stdin stdout stderr
    java里对应的就是System.in System.out System.err。
    操作系统启动程序的时候我们可以指定程序的输入流和输出流以及错误流指向哪里。

    System.err和System.out

    标准错误输出流和标准输出流是有区别的。输出流是有缓存的只有遇到换行符或者结束的时候才会输出,而err是直接输出的。

    shell或者cmd里的重定向

    重定向输出流
    2> 重定向错误输出流
    < 重定向输入流

    echo 1 > 1.txt
    echo < 1.txt 
    

    java子进程

    通过Runtime.exec会产生一个子进程。子进程的输入流 对应的就是父进程的输出流 子进程的输入流 对于父进程就是输出流。

    public static void ping(){
        try {
            Process process=Runtime.getRuntime().exec("ping www.baidu.com");
            InputStream in = process.getInputStream();
            BufferedReader br=new BufferedReader(new InputStreamReader(in,"gbk"));
            String line=null;
            while((line=br.readLine())!=null){
                System.out.println(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    

    process.getOutputStream实际就是指向子进程的标准输出流
    process.getErrorStream实际就是指向子进程的标准错误输出流
    process.getInputStream实际就是子进程的输入流

    由于计算机默认编码是gbk所以 获取ping的标准输出指向了gbk的Reader
    读取每一行的ping输出 打印到我们程序的输出 完成了最简单的ping功能

    IO就像插座 我们把任意的IO对接起来

    把cmd的IO和java的IO对接起来

    /**
     *  对接java的输出流到cmd的输入流
     *  必须调用
     *  最近\r\n模拟回车
     */
    public static void pipe(InputStream in,OutputStream out){
        try {
            BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(in,"utf8"));
            String line="";
            while((line=bufferedReader.readLine())!=null){
                out.write(line.getBytes("gbk"));
                out.write("\r\n".getBytes("gbk"));
                out.flush();
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    /**
     *  对接cmd的输入流到java的输出流
     */
    public static void pipe(InputStream in,String charset,OutputStream out,String outCharset) throws IOException {
        InputStreamReader br = new InputStreamReader(in, charset);
        char[] chunk=new char[2048];
        int len=0;
        StringBuilder stringBuilder=new StringBuilder();
        while((len=br.read(chunk,0,2048))!=-1){
            stringBuilder.append(chunk,0,len);
            System.out.write(stringBuilder.toString().getBytes(outCharset));
            System.out.flush();
            stringBuilder.delete(0,stringBuilder.length());
        }
    }
    
    /**
     *  启动三个线程 对接输入输出流和错误输出流
     */
    public static void socket() throws IOException {
        Process process=Runtime.getRuntime().exec("cmd");
        new Thread(new Runnable() {
            @Override
            public void run() {
                    pipe(System.in,process.getOutputStream());
            }
        }).start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    pipe(process.getInputStream(),"gbk",System.out,"utf8");
                } catch (IOException e) {
                    e.printStackTrace();
                }
                pipe(process.getInputStream(),System.out);
            }
        }).start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    pipe(process.getErrorStream(),"gbk",System.err,"utf8");
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }
    

    同理我们可以把cmd的IO对接到socket的IO上 那么就可以实现远程访问cmd

    socketIO和cmdIO对接

    启动Server之后再启动Client可以看到可以使用cmd

    public class CMDParent {
    
        /**
         * Sysytem.in 专用
         * @param out
         * @param charset
         */
        public static void SystemINpipe(OutputStream out,String charset){
            try {
                BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(System.in,"utf8"));
                String line="";
                while((line=bufferedReader.readLine())!=null){
                    out.write(line.getBytes(charset));
                    out.write("\r\n".getBytes(charset));
                    out.flush();
                }
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        public static void pipe(InputStream in, String charset, OutputStream out, String outCharset) throws IOException {
            InputStreamReader br = new InputStreamReader(in, charset);
            char[] chunk=new char[2048];
            int len=0;
            StringBuilder stringBuilder=new StringBuilder();
            while((len=br.read(chunk,0,2048))!=-1){
                stringBuilder.append(chunk,0,len);
                System.out.write(stringBuilder.toString().getBytes(outCharset));
                System.out.flush();
                stringBuilder.delete(0,stringBuilder.length());
            }
        }
    }
    
    public class CMDServer extends CMDParent{
    
        private Socket client;
    
        public CMDServer(Socket client) {
            try {
                Process process=Runtime.getRuntime().exec("cmd");
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            pipe(client.getInputStream(),"utf8",process.getOutputStream(),"gbk");
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }).start();
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            pipe(process.getInputStream(),"gbk",client.getOutputStream(),"utf8");
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }).start();
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            pipe(process.getErrorStream(),"gbk",client.getOutputStream(),"utf8");
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }).start();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        public static void main(String agrs[]) throws IOException {
            ServerSocket serverSocket=new ServerSocket(8091);
            Socket client;
            while((client=serverSocket.accept())!=null){
                new CMDServer(client);
            }
        }
    }
    
    
    public class CMDClient extends CMDParent {
    
        public static void main(String agrs[]) throws IOException {
            Socket socket=new Socket("localhost",8091);
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        pipe(socket.getInputStream(),"utf8",System.out,"utf8");
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }).start();
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                       SystemINpipe(socket.getOutputStream(),"utf8");
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }).start();
        }
    }
    

    相关文章

      网友评论

          本文标题:IO输入输出

          本文链接:https://www.haomeiwen.com/subject/ljnijxtx.html