NIO

NIO概述

為什么了有了IO她渴,還需要有NIO?

* NIO在JDK1.4后引入的

* NIO是面向塊(緩沖區(qū))編程匿沛,舊IO是面向流編程

*

* IO ? ? NIO

* 面向流 ? ? ? ? ?面向緩沖區(qū)

* 阻塞IO 非阻塞IO

* 無 ? ? ? ? ? 選擇器

*

* Java中針對IO的一些核心的包和接口、類

*

* java.nio 主要包含了各種與Buffer相關(guān)的類

* java.nio.channel 主要包含了與Channel和Selector相關(guān)的類和接口

* java.nio.charset 主要包含了與編碼相關(guān)的類接口

* java.nio.channels.spi 主要包含了與Channel相關(guān)的服務(wù)提供者編程接口

* javan.nio.charset.spi 主要包含了與charset相關(guān)的服務(wù)提供者編程接口

*

*

* 目前需要掌握的核心就是三個包

* Buffer

* Channel

* CharSet

*

* 面向緩沖區(qū)編程:

*? ? ? ? ?數(shù)據(jù)的讀寫必須經(jīng)過緩沖區(qū)

* ?我們可以使用Buffer所對應(yīng)的子類來數(shù)據(jù)從通道(Channel)流向緩沖區(qū)

* ?從緩沖區(qū)寫到通道叫做讀取緩沖區(qū)

Buffer緩沖區(qū)

Buffer

* Buffer是一個抽象類

* 子類有

*? ? ? ? ?ByteBuffer, CharBuffer, DoubleBuffer, FloatBuffer, IntBuffer, LongBuffer, ShortBuffer

*

* 核心類

*? ? ? ? ?ByteBuffer和CharBuffer

* ByteBuffer有一個子類 MappedByteBuffer

* MappedByteBuffer類能夠?qū)⑽募苯佑成涞絻?nèi)存中凭戴,那么這樣我們就可以像訪問內(nèi)存一樣訪問文件函喉,非常方便

*

* 獲取Buffer

*? ? ? ? ?獲取ByteBuffer

*? ? ? ? ? ? ? ? ?static ByteBuffer allocate(int capacity)

? ? ? ? ? ? ? ? ? ? ? ? ?分配一個新的字節(jié)緩沖區(qū)反璃。

? ? ? ? ? ? ? ?static ByteBuffer allocateDirect(int capacity)

? ? ? ? ? ? ? ? ? ? ? ? ?分配新的直接字節(jié)緩沖區(qū)。

? ? ? ? 二者獲取Buffer的區(qū)別

? ? ? ? 1.創(chuàng)建普通Buffer成本低秃臣,讀寫的效率不高

? ? ? ? 2.因為創(chuàng)建直接Buffer成本高涧衙,所以我們一般用在Buffer生存周期較長的時候使用

? ? ? ? 3.只有ByteBuffer才能夠創(chuàng)建直接Buffer,其他的Buffer對象是不能夠創(chuàng)建

? ? ? ? 4.如果創(chuàng)建了直接Buffer但是我又想要使用其他Buffer的功能奥此,可以將ByteBuffer轉(zhuǎn)換成其他Buffer

? ? ? ?? ? ? ? ? ? ? ? ?asIntBuffer()

* 四個非常重要的概念

*? ? ? ? ?capacity: 緩沖區(qū)的容量弧哎,不可以為負數(shù),一旦創(chuàng)建了就不能夠改變

* ?limit: 無效緩沖區(qū)的第一個位置索引得院,limit后面的數(shù)據(jù)既不可讀傻铣,也不可寫

* ?position : 下一個可以被讀取或者寫入的緩沖區(qū)位置索引

* ?mark: 標記索引,該索引能夠用于下次讀取或者寫入祥绞,它只能夠在0-position之間

* ?

* ?四個系數(shù)的關(guān)系:

* ? ? ? ? ?0 < mark < postion < limit < capacity

* ?

* ?五個方法

* ? ? ? ? ?flip(): 將寫模式切換為讀模式非洲, 將limit的值改為postion的值,同時將postion歸0

* ? ? ? ? ? ? ? ? ? ? ? ? ?特點: 就是為下一次數(shù)據(jù)的讀取做好準備

* ? ? ? ? ?clear(): 將讀模式切換為寫模式蜕径,將limit改為capacity的值两踏,同時將postion歸0

* ? ? ? ? ? ? ? ? ? ? ? ? ?特點: 就是為下一次數(shù)據(jù)的寫入做好準備

* ? ? ? ? ?put(): 相對讀取,向Buffer中存儲數(shù)據(jù)

* ? ? ? ? ?get(): 相對讀取兜喻,從Buffer中獲取數(shù)據(jù)

* ? ? ? ? ?hasRemaining(): 判斷當(dāng)前位置和limit之間是否還有元素可處理

*

* 絕對讀取: get(index) 不會影響position的位置

* 相對讀取: put() get() 會影響梦染,每次讀取一次,指針后移

*/

public class NIODemo02 {

? ? ? ?public static void main(String[] args) {

// ? ? ? ? ? ? ? ?ByteBuffer buffer = ByteBuffer.allocate(5);

// ? ? ? ? ? ? ? ?ByteBuffer buffer2 = ByteBuffer.allocateDirect(10);

? ? ? ? ? ? ? ?CharBuffer buffer = CharBuffer.allocate(8);

? ? ? ? ? ? ? ?// Buffer已經(jīng)準備好了向Buffer中寫數(shù)據(jù) ? ?寫模式

? ? ? ? ? ? ? ?System.out.println("capacity:" + buffer.capacity()); // 8

? ? ? ? ? ? ? ?System.out.println("limit:" + buffer.limit()); // 8

? ? ? ? ? ? ? ?System.out.println("position:" + buffer.position()); // 0


? ? ? ? ? ? ? ?buffer.put('a');

? ? ? ? ? ? ? ?buffer.put('b');

? ? ? ? ? ? ? ?buffer.put('c');

? ? ? ? ? ? ? ?System.out.println("------------------------");


? ? ? ? ? ? ? ?System.out.println("capacity:" + buffer.capacity()); // 8

? ? ? ? ? ? ? ?System.out.println("limit:" + buffer.limit()); // 8

? ? ? ? ? ? ? ?System.out.println("position:" + buffer.position()); // 3


? ? ? ? ? ? ? ?System.out.println("------------------------");

? ? ? ? ? ? ? ?// 切換模式 ?,limit變?yōu)閜osition的位置然后將position變?yōu)?

? ? ? ? ? ? ? ?buffer.flip();

? ? ? ? ? ? ? ?System.out.println("capacity:" + buffer.capacity()); // 8

? ? ? ? ? ? ? ?System.out.println("limit:" + buffer.limit()); // 3

? ? ? ? ? ? ? ?System.out.println("position:" + buffer.position()); // 0


? ? ? ? ? ? ? ?System.out.println("------------------------");

// ? ? ? ? ? ? ? ?char ch = 0;

// ? ? ? ? ? ? ? ?ch = buffer.get();

// ? ? ? ? ? ? ? ?System.out.println(ch);

// ? ? ? ? ? ? ? ?ch = buffer.get();

// ? ? ? ? ? ? ? ?System.out.println(ch);

// ? ? ? ? ? ? ? ?

//// ? ? ? ? ? ? ? ?System.out.println("capacity:" + buffer.capacity()); // 8

//// ? ? ? ? ? ? ? ?System.out.println("limit:" + buffer.limit()); // 3

//// ? ? ? ? ? ? ? ?System.out.println("position:" + buffer.position()); // 2

// ? ? ? ? ? ? ? ?ch = buffer.get();

// ? ? ? ? ? ? ? ?System.out.println(ch);

// ? ? ? ? ? ? ? ?

// ? ? ? ? ? ? ? ?ch = buffer.get();

// ? ? ? ? ? ? ? ?System.out.println(ch);


? ? ? ? ? ? ? ?int ch = 0;

? ? ? ? ? ? ? ?while (buffer.hasRemaining()) {

? ? ? ? ? ? ? ? ? ? ? ?ch = buffer.get();

? ? ? ? ? ? ? ? ? ? ? ?System.out.println((char)ch);

? ? ? ? ? ? ? ?}


? ? ? ? ? ? ? ?System.out.println("------------------");

? ? ? ? ? ? ? ?buffer.clear(); // 將postion 清 0 帕识,將limit = capacity


? ? ? ? ? ? ? ?System.out.println("capacity:" + buffer.capacity()); // 8

? ? ? ? ? ? ? ?System.out.println("limit:" + buffer.limit()); // 8

? ? ? ? ? ? ? ?System.out.println("position:" + buffer.position()); // 0


? ? ? ? ? ? ? ?// 注意: 調(diào)用clear方法只是將讀模式改為寫模式泛粹,并不會清空緩沖區(qū)的數(shù)據(jù)

? ? ? ? ? ? ? ?System.out.println(buffer.get(1));

? ? ? ? ? ? ? ?System.out.println("執(zhí)行絕對讀取之后Buffer的position位置:" + buffer.position());

? ? ? ?}

}

Channel通道

* Channel原理類似于傳統(tǒng)的流對象, FileInputStream FileOutputStream

* 但是有兩個主要的區(qū)別

*? ? ? ? ?1.Channel能夠?qū)⒅付ǖ牟糠只蛘呷课募成涞絻?nèi)存中

*? ? ? ? ? ? ? ? ?全部映射

*? ? ? ? ? ? ? ? ? ? ? ? ?MappedByteBuffer

*? ? ? ? ? ? ? ? ?部分文件映射

* ?2.程序如果想要讀取Channel中的數(shù)據(jù)肮疗,不能夠直接讀寫晶姊,必須經(jīng)過Buffer

* ?

* ?Java中為Channel提供了如下常用的類

* ?

* ?FileChannel 和文件相關(guān)的通道

* ?DatagramChannel 和UDP協(xié)議傳輸數(shù)據(jù)相關(guān)的通道

* ?SocketChannel 和TCP協(xié)議相關(guān)的數(shù)據(jù)傳輸通道

* ?ServerSocket 和TCP協(xié)議相關(guān)的數(shù)據(jù)傳輸通道

* ?

* ?獲取FileChannel對象

* ?和文件相關(guān)的普通流有哪些?

* ? ? ? ? ?FileInputStream FileOutputStream RandomAccessFile

* ?常用的方法

* ?read() : 將Channel中的數(shù)據(jù)讀取到Buffer中

* ?write() : 向Buffer中寫入數(shù)據(jù)

* ?map(): 將channel中的數(shù)據(jù)全部或者部分映射到Buffer中

* ? ? ? ? ? ? ? ? ?inChannel.map(mode, position, size)

* ? ? ? ? ? ? ? ? ?MappedByteBuffer mappBuffer = inChannel.map(MapMode.READ_ONLY, 0, srcFile.length());

*/

CharSet字符集

Charset 理解為現(xiàn)實生活的編碼表對象

*/

public class NIODemo05 {

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

? ? ? ? ? ? ? ?// 獲取當(dāng)前JDK所支持的所有編碼類型

// ? ? ? ? ? ? ? ?SortedMap<String, Charset> map = Charset.availableCharsets();

// ? ? ? ? ? ? ? ?

// ? ? ? ? ? ? ? ?for (String key : map.keySet()) {

// ? ? ? ? ? ? ? ? ? ? ? ?Charset charset = map.get(key);

// ? ? ? ? ? ? ? ? ? ? ? ?System.out.println(charset);

// ? ? ? ? ? ? ? ?}


? ? ? ? ? ? ? ?// 知道了對應(yīng)JDK認可的字符集別名后,那么我們就可以來獲取對應(yīng)的字符集對象

? ? ? ? ? ? ? ?Charset charset = Charset.forName("GBK");


? ? ? ? ? ? ? ?// 創(chuàng)建編碼器 ?編碼 字符/字符串/字符數(shù)組 --> 字節(jié)

? ? ? ? ? ? ? ?CharsetEncoder encoder = charset.newEncoder();

? ? ? ? ? ? ? ?// 創(chuàng)建解碼器 ?解碼 上述相反

? ? ? ? ? ? ? ?CharsetDecoder decoder = charset.newDecoder();


? ? ? ? ? ? ? ?CharBuffer charBuffer = CharBuffer.allocate(10);

? ? ? ? ? ? ? ?charBuffer.put("abc");

? ? ? ? ? ? ? ?charBuffer.flip();


? ? ? ? ? ? ? ?ByteBuffer byteBuffer = encoder.encode(charBuffer);


? ? ? ? ? ? ? ?for (int i = 0; i < byteBuffer.limit(); i++) {

? ? ? ? ? ? ? ? ? ? ? ?System.out.println(byteBuffer.get(i));

? ? ? ? ? ? ? ?}


? ? ? ? ? ? ? ?System.out.println(decoder.decode(byteBuffer));

? ? ? ?}

}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末伪货,一起剝皮案震驚了整個濱河市们衙,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌碱呼,老刑警劉巖蒙挑,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異愚臀,居然都是意外死亡忆蚀,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進店門懊悯,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蜓谋,“玉大人,你說我怎么就攤上這事炭分√一溃” “怎么了?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我皱蹦,道長欺冀,這世上最難降的妖魔是什么望忆? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘胰坟。我一直安慰自己,他們只是感情好泞辐,可當(dāng)我...
    茶點故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布笔横。 她就那樣靜靜地躺著,像睡著了一般咐吼。 火紅的嫁衣襯著肌膚如雪吹缔。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天锯茄,我揣著相機與錄音厢塘,去河邊找鬼茶没。 笑死,一個胖子當(dāng)著我的面吹牛晚碾,可吹牛的內(nèi)容都是我干的抓半。 我是一名探鬼主播,決...
    沈念sama閱讀 38,432評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼迄薄,長吁一口氣:“原來是場噩夢啊……” “哼琅关!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起讥蔽,我...
    開封第一講書人閱讀 37,088評論 0 261
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎画机,沒想到半個月后冶伞,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,586評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡步氏,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年响禽,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片荚醒。...
    茶點故事閱讀 38,137評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡芋类,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出界阁,到底是詐尸還是另有隱情侯繁,我是刑警寧澤,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布泡躯,位于F島的核電站贮竟,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏较剃。R本人自食惡果不足惜咕别,卻給世界環(huán)境...
    茶點故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望写穴。 院中可真熱鬧惰拱,春花似錦、人聲如沸啊送。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽删掀。三九已至翔冀,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間披泪,已是汗流浹背纤子。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人控硼。 一個月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓泽论,卻偏偏與公主長得像,于是被迫代替她去往敵國和親卡乾。 傳聞我的和親對象是個殘疾皇子翼悴,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,901評論 2 345

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