NIO主要有三大核心部分:Channel(通道),Buffer(緩沖區(qū)), Selector。傳統(tǒng)IO基于字節(jié)流和字符流進(jìn)行操作,而NIO基于Channel和Buffer(緩沖區(qū))進(jìn)行操作,數(shù)據(jù)總是從通道讀取到緩沖區(qū)中,或者從緩沖區(qū)寫入到通道中。Selector(選擇區(qū))用于多個(gè)通道的事件(比如:連接打開,數(shù)據(jù)到達(dá))。因此,單個(gè)線程可以多個(gè)數(shù)據(jù)通道。
NIO和傳統(tǒng)IO(一下簡稱IO)之間個(gè)的區(qū)別是,IO是面向流的,NIO是面向緩沖區(qū)的。 Java IO面向流意味著每次從流中讀一個(gè)或多個(gè)字節(jié),直至讀取所有字節(jié),它們沒有被緩存在任何地方。此外,它不能前后移動(dòng)流中的數(shù)據(jù)。如果需要前后移動(dòng)從流中讀取的數(shù)據(jù),需要先將它緩存到一個(gè)緩沖區(qū)。NIO的緩沖導(dǎo)向方法略有不同。數(shù)據(jù)讀取到一個(gè)它稍后處理的緩沖區(qū),需要時(shí)可在緩沖區(qū)中前后移動(dòng)。這就增加了處理過程中的靈活性。但是,還需要檢查是否該緩沖區(qū)中包含所有您需要處理的數(shù)據(jù)。而且,需確保當(dāng)更多的數(shù)據(jù)讀入緩沖區(qū)時(shí),不要覆蓋緩沖區(qū)里尚未處理的數(shù)據(jù)。
IO的各種流是阻塞的。這意味著,當(dāng)一個(gè)線程調(diào)用read() 或 write()時(shí),該線程被阻塞,直到有一些數(shù)據(jù)被讀取,或數(shù)據(jù)完全寫入。該線程在此期間不能再干任何事情了。 NIO的非阻塞模式,使一個(gè)線程從某通道發(fā)送請求讀取數(shù)據(jù),但是它僅能得到目前可用的數(shù)據(jù),如果目前沒有數(shù)據(jù)可用時(shí),就什么都不會(huì)獲取。而不是保持線程阻塞,所以直至數(shù)據(jù)變得可以讀取之前,該線程可以繼續(xù)做其他的事情。 非阻塞寫也是如此。一個(gè)線程請求寫入一些數(shù)據(jù)到某通道,但不需要等待它完全寫入,這個(gè)線程同時(shí)可以去做別的事情。 線程通常將非阻塞IO的空閑時(shí)間用于在其它通道上執(zhí)行IO操作,所以一個(gè)單獨(dú)的線程現(xiàn)在可以管理多個(gè)輸入和輸出通道(channel)。
Channel
首先說一下Channel,國內(nèi)大多翻譯成“通道”。Channel和IO中的Stream(流)是差不多一個(gè)等級(jí)的。只不過Stream是單向的,譬如:InputStream, OutputStream.而Channel是雙向的,既可以用來進(jìn)行讀操作,又可以用來進(jìn)行寫操作。
NIO中的Channel的主要實(shí)現(xiàn)有:·
FileChannel··
DatagramChannel··
SocketChannel·
ServerSocketChannel·
這里看名字就可以猜出個(gè)所以然來:分別可以對應(yīng)文件IO、UDP和TCP(Server和Client)。下面演示的案例基本上就是圍繞這4個(gè)類型的Channel進(jìn)行陳述的。
Buffer
NIO中的關(guān)鍵Buffer實(shí)現(xiàn)有:ByteBuffer, CharBuffer, DoubleBuffer, FloatBuffer, IntBuffer, LongBuffer, ShortBuffer,分別對應(yīng)基本數(shù)據(jù)類型: byte, char, double, float, int, long, short。當(dāng)然NIO中還有MappedByteBuffer, HeapByteBuffer, DirectByteBuffer等這里先不進(jìn)行陳述。
Selector
Selector運(yùn)行單線程處理多個(gè)Channel,如果你的應(yīng)用打開了多個(gè)通道,但每個(gè)連接的流量都很低,使用Selector就會(huì)很方便。例如在一個(gè)聊天服務(wù)器中。要使用Selector, 得向Selector注冊Channel,然后調(diào)用它的select()方法。這個(gè)方法會(huì)一直阻塞到某個(gè)注冊的通道有事件就緒。一旦這個(gè)方法返回,線程就可以處理這些事件,事件的例子有如新的連接進(jìn)來、數(shù)據(jù)接收等。