IO輸入輸出

介紹

IO 實(shí)際就是輸入流IN 輸出 OUT
輸出流分stderr(標(biāo)準(zhǔn)錯(cuò)誤輸出) 和stdout(標(biāo)準(zhǔn)輸出),c語言里 對(duì)應(yīng)的就是全局對(duì)象stdin stdout stderr
java里對(duì)應(yīng)的就是System.in System.out System.err。
操作系統(tǒng)啟動(dòng)程序的時(shí)候我們可以指定程序的輸入流和輸出流以及錯(cuò)誤流指向哪里。

System.err和System.out

標(biāo)準(zhǔn)錯(cuò)誤輸出流和標(biāo)準(zhǔn)輸出流是有區(qū)別的。輸出流是有緩沖的,只有遇到換行符或者結(jié)束的時(shí)候才會(huì)輸出,而err是直接輸出的。

shell或者cmd里的重定向

> 重定向輸出流
2> 重定向錯(cuò)誤輸出流
< 重定向輸入流

echo 1 > 1.txt
echo < 1.txt 

java子進(jìn)程

通過Runtime.exec會(huì)產(chǎn)生一個(gè)子進(jìn)程。子進(jìn)程的輸入流 對(duì)應(yīng)的就是父進(jìn)程的輸出流 子進(jìn)程的輸入流 對(duì)于父進(jìn)程就是輸出流。

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.getInputStream實(shí)際就是指向子進(jìn)程的標(biāo)準(zhǔn)輸出流
process.getErrorStream實(shí)際就是指向子進(jìn)程的標(biāo)準(zhǔn)錯(cuò)誤輸出流
process.getOutputStream實(shí)際就是子進(jìn)程的輸入流

由于計(jì)算機(jī)默認(rèn)編碼是gbk所以 獲取ping的標(biāo)準(zhǔn)輸出指向了gbk的Reader
讀取每一行的ping輸出 打印到我們程序的輸出 完成了最簡(jiǎn)單的ping功能

IO就像插座 我們把任意的IO對(duì)接起來

把cmd的IO和java的IO對(duì)接起來

/**
 *  對(duì)接java的輸出流到cmd的輸入流
 *  必須調(diào)用
 *  最近\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();
    }
}

/**
 *  對(duì)接cmd的輸入流到j(luò)ava的輸出流
 */
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());
    }
}

/**
 *  啟動(dòng)三個(gè)線程 對(duì)接輸入輸出流和錯(cuò)誤輸出流
 */
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對(duì)接到socket的IO上 那么就可以實(shí)現(xiàn)遠(yuǎn)程訪問cmd

socketIO和cmdIO對(duì)接

啟動(dòng)Server之后再啟動(dòng)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();
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • 介紹 IO 實(shí)際就是輸入流IN 輸出 OUT輸出流分stderr(標(biāo)準(zhǔn)錯(cuò)誤輸出) 和stdout(標(biāo)準(zhǔn)輸出),c語...
    Charon_Pluto閱讀 368評(píng)論 0 0
  • 介紹 IO 實(shí)際就是輸入流IN 輸出 OUT輸出流分stderr(標(biāo)準(zhǔn)錯(cuò)誤輸出) 和stdout(標(biāo)準(zhǔn)輸出),c語...
    代碼界的掃地僧閱讀 293評(píng)論 0 1
  • 一.java.io.File類 java.io.File類用于表示文件/目錄 File只用于表示文件的信息(名稱,...
    liangxifeng833閱讀 781評(píng)論 0 1
  • Java中輸入/輸出的類存放在java.io包中 輸入流類都是抽象類InputStream(字節(jié)輸入流)或抽象類R...
    朱Simon閱讀 642評(píng)論 0 0
  • 輸入輸出流。 InputStream與OutputStream 讀與寫 使用InputStream讀取字節(jié)并轉(zhuǎn)為字...
    BlackNeko閱讀 978評(píng)論 0 0