io和nio的區別

什麼是通道Channel(通道)
顧名思義,就是通向什麼的道路,爲某個提供了渠道。在傳統IO中,我們要讀取一個文件中的內容,通常是像下面這樣讀取的:

public static void copy_1(){
FileInputStream in = null;
FileOutputStream out = null;
try {
in = new FileInputStream("c:\timg.jpg");
out = new FileOutputStream("D:\timg.jpg");
int ch = 0;
while((ch=in.read())!=-1){//這個方法是對這個流一個一個字節的讀,返回的int就是這個字節的int表示方式
out.write(ch);
}
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
    if(out!=null){
        out.close();
    }
} catch (IOException e) {
    e.printStackTrace();
}
try {
    if(in!=null){
        in.close();
    }
} catch (Exception e2) {
    e2.printStackTrace();
}
}
}
public static void copy_2(){
FileInputStream in = null;
FileOutputStream out = null;
try {
in=new FileInputStream("c:\timg.jpg");
out=new FileOutputStream("d:\timg.jpg");
byte[] buffer = new byte[1024];
int len = 0;
while((len=in.read(buffer))!=-1){//這個方法是先規定一個數組長度,將這個流中的字節緩衝到數組b中,返回的這個數組中的字節個數,這個緩衝區沒有滿的話,則返回真實的字節個數,到未尾時都返回-1
out.write(buffer, 0, len);
}
} catch (Exception e) {
e.printStackTrace();
}finally {
try {
if(out!=null){
out.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if(in!=null){
in.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
}

這裏的InputStream實際上就是爲讀取文件提供一個通道的。

  因此可以將NIO 中的Channel同傳統IO中的Stream來類比,但是要注意,傳統IO中,Stream是單向的,比如InputStream只能進行讀取操作,OutputStream只能進行寫操作。而Channel是雙向的,既可用來進行讀操作,又可用來進行寫操作。
以下是常用的幾種通道:

FileChannel

SocketChanel

ServerSocketChannel

DatagramChannel

通過使用FileChannel可以從文件讀或者向文件寫入數據;通過SocketChannel,以TCP來向網絡連接的兩端讀寫數據;通過ServerSocketChanel能夠監聽客戶端發起的TCP連接,併爲每個TCP連接創建一個新的SocketChannel來進行數據讀寫;通過DatagramChannel,以UDP協議來向網絡連接的兩端讀寫數據。

public class Test {

public static void main(String[] args) throws IOException  {

    File file = new File("data.txt");

    FileOutputStream outputStream = new FileOutputStream(file);

    FileChannel channel = outputStream.getChannel();

    ByteBuffer buffer = ByteBuffer.allocate(1024);

    String string = "java nio";

    buffer.put(string.getBytes());

    buffer.flip();     //此處必須要調用buffer的flip方法

    channel.write(buffer);

    channel.close();

    outputStream.close();

}  
    }

通過上面的程序會向工程目錄下的data.txt文件寫入字符串"java nio",注意在調用channel的write方法之前必須調用buffer的flip方法,否則無法正確寫入內容

什麼是緩衝區Buffer(緩衝區)
 Buffer,故名思意,緩衝區,實際上是一個容器,是一個連續數組。Channel提供從文件、網絡讀取數據的渠道,但是讀取或寫入的數據都必須經由Buffer。
在NIO中,Buffer是一個頂層父類,它是一個抽象類,常用的Buffer的子類有:

ByteBuffer

IntBuffer

CharBuffer

LongBuffer

DoubleBuffer

FloatBuffer

ShortBuffer

  如果是對於文件讀寫,上面幾種Buffer都可能會用到。但是對於網絡讀寫來說,用的最多的是ByteBuffer

什麼是選擇器Selector(選擇器)
Selector運行單線程處理多個Channel,如果你的應用打開了多個通道,但每個連接的流量都很低,使用Selector就會很方便。例如在一個聊天服務器中。要使用Selector, 得向Selector註冊Channel,然後調用它的select()方法。這個方法會一直阻塞到某個註冊的通道有事件就緒。一旦這個方法返回,線程就可以處理這些事件,事件的例子有如新的連接進來、數據接收等。

io和nio的區別
IO是面向流的,NIO是面向緩衝的;
IO是阻塞的,NIO是非阻塞的;
IO是單線程的,NIO 是通過選擇器來模擬多線程的;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章