資源描述:
《Java NIO API詳解》由會(huì)員上傳分享,免費(fèi)在線閱讀,更多相關(guān)內(nèi)容在工程資料-天天文庫(kù)。
1、JavaNIOAPI詳解在JDK1.4以前,Java的IO操作集中在java.io這個(gè)包中,是基于流的阻塞(blocking)API。對(duì)于大多數(shù)應(yīng)用來(lái)說(shuō),這樣的API使用很方便,然而,一些對(duì)性能要求較高的應(yīng)用,尤其是服務(wù)端應(yīng)用,往往需要一個(gè)更為有效的方式來(lái)處理IO。從JDK1.4起,NIOAPI作為一個(gè)基于緩沖區(qū),并能提供非阻塞(non-blocking)IO操作的API被引入。本文對(duì)其進(jìn)行深入的介紹。?NIOAPI主要集中在java.nio和它的subpackages中:?java.nio定義了Buffer及其數(shù)據(jù)類(lèi)型相關(guān)的子類(lèi)。其中被java.nio.channels中的類(lèi)用來(lái)進(jìn)行IO操
2、作的ByteBuffer的作用非常重要。?java.nio.channels定義了一系列處理IO的Channel接口以及這些接口在文件系統(tǒng)和網(wǎng)絡(luò)通訊上的實(shí)現(xiàn)。通過(guò)Selector這個(gè)類(lèi),還提供了進(jìn)行非阻塞IO操作的辦法。這個(gè)包可以說(shuō)是NIOAPI的核心。?java.nio.channels.spi定義了可用來(lái)實(shí)現(xiàn)channel和selectorAPI的抽象類(lèi)。?java.nio.charset???????定義了處理字符編碼和解碼的類(lèi)。?java.nio.charset.spi???????定義了可用來(lái)實(shí)現(xiàn)charsetAPI的抽象類(lèi)。?java.nio.channels.spi和java.
3、nio.charset.spi這兩個(gè)包主要被用來(lái)對(duì)現(xiàn)有NIOAPI進(jìn)行擴(kuò)展,在實(shí)際的使用中,我們一般只和另外的3個(gè)包打交道。下面將對(duì)這3個(gè)包一一介紹。?Packagejava.nio這個(gè)包主要定義了Buffer及其子類(lèi)。Buffer定義了一個(gè)線性存放primitivetype數(shù)據(jù)的容器接口。對(duì)于除boolean以外的其他primitivetype,都有一個(gè)相應(yīng)的Buffer子類(lèi),ByteBuffer是其中最重要的一個(gè)子類(lèi)。?下面這張UML類(lèi)圖描述了java.nio中的類(lèi)的關(guān)系:?Buffer定義了一個(gè)可以線性存放primitivetype數(shù)據(jù)的容器接口。Buffer主要包含了與類(lèi)型(byte
4、,char…)無(wú)關(guān)的功能。值得注意的是Buffer及其子類(lèi)都不是線程安全的。?每個(gè)Buffer都有以下的屬性:?capacity這個(gè)Buffer最多能放多少數(shù)據(jù)。capacity一般在buffer被創(chuàng)建的時(shí)候指定。limit在Buffer上進(jìn)行的讀寫(xiě)操作都不能越過(guò)這個(gè)下標(biāo)。當(dāng)寫(xiě)數(shù)據(jù)到buffer中時(shí),limit一般和capacity相等,當(dāng)讀數(shù)據(jù)時(shí),limit代表buffer中有效數(shù)據(jù)的長(zhǎng)度。position讀/寫(xiě)操作的當(dāng)前下標(biāo)。當(dāng)使用buffer的相對(duì)位置進(jìn)行讀/寫(xiě)操作時(shí),讀/寫(xiě)會(huì)從這個(gè)下標(biāo)進(jìn)行,并在操作完成后,buffer會(huì)更新下標(biāo)的值。mark一個(gè)臨時(shí)存放的位置下標(biāo)。調(diào)用mark()會(huì)
5、將mark設(shè)為當(dāng)前的position的值,以后調(diào)用reset()會(huì)將position屬性設(shè)置為mark的值。mark的值總是小于等于position的值,如果將position的值設(shè)的比mark小,當(dāng)前的mark值會(huì)被拋棄掉。?這些屬性總是滿(mǎn)足以下條件:0<=?mark?<=?position?<=?limit?<=?capacity?limit和position的值除了通過(guò)limit()和position()函數(shù)來(lái)設(shè)置,也可以通過(guò)下面這些函數(shù)來(lái)改變:?Bufferclear()把position設(shè)為0,把limit設(shè)為capacity,一般在把數(shù)據(jù)寫(xiě)入Buffer前調(diào)用。Bufferfli
6、p()把limit設(shè)為當(dāng)前position,把position設(shè)為0,一般在從Buffer讀出數(shù)據(jù)前調(diào)用。Bufferrewind()把position設(shè)為0,limit不變,一般在把數(shù)據(jù)重寫(xiě)入Buffer前調(diào)用。?Buffer對(duì)象有可能是只讀的,這時(shí),任何對(duì)該對(duì)象的寫(xiě)操作都會(huì)觸發(fā)一個(gè)ReadOnlyBufferException。isReadOnly()方法可以用來(lái)判斷一個(gè)Buffer是否只讀。?ByteBuffer在Buffer的子類(lèi)中,ByteBuffer是一個(gè)地位較為特殊的類(lèi),因?yàn)樵趈ava.io.channels中定義的各種channel的IO操作基本上都是圍繞ByteBuffer
7、展開(kāi)的。?ByteBuffer定義了4個(gè)static方法來(lái)做創(chuàng)建工作:?ByteBufferallocate(intcapacity)創(chuàng)建一個(gè)指定capacity的ByteBuffer。ByteBufferallocateDirect(intcapacity)創(chuàng)建一個(gè)direct的ByteBuffer,這樣的ByteBuffer在參與IO操作時(shí)性能會(huì)更好(很有可能是在底層的實(shí)現(xiàn)使用了DMA技術(shù)),相應(yīng)的,創(chuàng)建