介紹
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();
}
}