學(xué)習(xí)筆記——NIO(1)

Java NIO(New IO)
是一個(gè)可以替代標(biāo)準(zhǔn)Java IO API的IO API(從Java 1.4開(kāi)始),Java NIO提供了與標(biāo)準(zhǔn)IO不同的IO工作方式。
它有三個(gè)核心分別是:Channel、Buffer和Selector

Channel

Channel翻譯過(guò)來(lái)是“通道、頻道”,其實(shí)可以用流的概念簡(jiǎn)單的去概括他,數(shù)據(jù)可以從Channel讀到Buffer中,也可以從Buffer 寫(xiě)到Channel中。其實(shí)理解起來(lái)很簡(jiǎn)單:Buffer是緩存嘛,緩存的東西我們當(dāng)然要可以取出來(lái)了,向誰(shuí)取呢?Channel唄;我們當(dāng)然也要向緩存里存東西啊,誰(shuí)去向緩存里填充東西?Channel唄;Easy~~

Buffer

Buffer就是“緩存”的意思嘛,沒(méi)啥好說(shuō)的,它覆蓋了可以用IO發(fā)送的基本數(shù)據(jù)類(lèi)型。

Selector

Selector厲害了!翻譯來(lái)是“選擇器”。
我們平時(shí)的BIO是:即客戶(hù)端有連接請(qǐng)求時(shí)服務(wù)器端就需要啟動(dòng)一個(gè)線程進(jìn)行處理,如果這個(gè)連接不做任何事情會(huì)造成不必要的線程開(kāi)銷(xiāo)。但是現(xiàn)在是NIO了,NIO提供了Selector,服務(wù)器實(shí)現(xiàn)模式從一個(gè)連接對(duì)應(yīng)一個(gè)線程轉(zhuǎn)化為了一個(gè)請(qǐng)求對(duì)應(yīng)。一個(gè)線程,即客戶(hù)端發(fā)送的連接請(qǐng)求都會(huì)注冊(cè)到多路復(fù)用器上,多路復(fù)用器輪詢(xún)到連接有I/O請(qǐng)求時(shí)才啟動(dòng)一個(gè)線程進(jìn)行處理。
說(shuō)起來(lái)很復(fù)雜,其實(shí)不然:
比如說(shuō),我想使用多個(gè)Channel,但是我不必開(kāi)啟多個(gè)線程去管理,我在這里就可以利用Selector去進(jìn)行管理這些Channel。

Channel的使用

這里記一下Channel:
NIO的Channel類(lèi)似流,但是不能完全當(dāng)做流:
1.流的讀寫(xiě)是單向的,但是Channel是可以通過(guò)一個(gè)Channel讀和寫(xiě)的,是雙向的。
2.Channel是可以異步讀寫(xiě)的。
3.Channel的使用是需要Buffer配合的。
簡(jiǎn)單的寫(xiě)一下Channel的小栗子:

RandomAccessFile aFile = new RandomAccessFile("data/nio-data.txt", "rw");
FileChannel inChannel = aFile.getChannel();

ByteBuffer buf = ByteBuffer.allocate(48);

int bytesRead = inChannel.read(buf);
while (bytesRead != -1) {

System.out.println("Read " + bytesRead);
buf.flip();

while(buf.hasRemaining()){
System.out.print((char) buf.get());
}

buf.clear();
bytesRead = inChannel.read(buf);
}
aFile.close();

上面的程序是在并發(fā)編程網(wǎng)照著敲下來(lái)的,而且沒(méi)加注釋?zhuān)覀儠?huì)發(fā)現(xiàn)出現(xiàn)了喜聞樂(lè)見(jiàn)的中文亂碼問(wèn)題ㄟ( ▔, ▔ )ㄏ
~只能通過(guò)自己嘗試去解決啦!
經(jīng)過(guò)查找資料寫(xiě)了如下的代碼,并且加了注釋?zhuān)?/p>

package NIOTest;

import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;

/**
 * NIO
 * Created by AceCream on 2017/5/12.
 */
public class TestChannel {

    public static void main(String[] args) throws IOException {
        /**
         *
         * RandomAccessFile是用來(lái)訪問(wèn)那些保存數(shù)據(jù)記錄的文件的,
         * 你就可以用seek( )方法來(lái)訪問(wèn)記錄,并進(jìn)行讀寫(xiě)了。這些記錄的大小不必相同;
         * !但是其大小和位置必須是可知的。但是該類(lèi)僅限于操作文件。!
         * RandomAccessFile的工作方式是,把DataInputStream和DataOutputStream結(jié)合起來(lái),
         * 再加上它自己的一些方法
         */
        Charset charset = Charset.forName("UTF-8");
        //解碼器
        CharsetDecoder decoder = charset.newDecoder();
        RandomAccessFile aFile = new RandomAccessFile("nio-data.txt","rw");
        
        //獲取Channel
        FileChannel inChannel = aFile.getChannel();
        //創(chuàng)建一個(gè)容量為256字節(jié)的ByteBuffer
        ByteBuffer buf = ByteBuffer.allocate(48);
        //創(chuàng)建一個(gè)容量為256字節(jié)的CharBuffer
        CharBuffer cb = CharBuffer.allocate(48);
//      System.out.println("ByteBuffer信息:"+buf);
        int count = inChannel.read(buf);
        while (count!=-1){
            System.out.println("count= "+count);
            //注意 buf.flip() 的調(diào)用,首先讀取數(shù)據(jù)到Buffer,然后反轉(zhuǎn)Buffer,接著再?gòu)腂uffer中讀取數(shù)據(jù)。
            buf.flip();
            //用解碼器進(jìn)行解碼
            decoder.decode(buf, cb, false);
            //解碼后,charbuffer再flip一下
            cb.flip();
            //這里為了避免中文亂碼問(wèn)題,采用CharBuffer,通過(guò)設(shè)置CharSet字符集,將byte編碼成char去測(cè)試
            while (cb.hasRemaining()){
                System.out.print(cb.get());
            }
            buf.clear();
            cb.clear();
            count = inChannel.read(buf);
            System.out.println();
        }
        //RandomAccessFile的close方法會(huì)將對(duì)應(yīng)的非空channel關(guān)閉。
        aFile.close();
    }
}

做一些解釋?zhuān)?br> Q:為什么不關(guān)閉Channel?
A:因?yàn)殛P(guān)閉了RandomAccessFile,同時(shí)就關(guān)閉了非空的Channel~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Java NIO(New IO)是從Java 1.4版本開(kāi)始引入的一個(gè)新的IO API,可以替代標(biāo)準(zhǔn)的Java I...
    JackChen1024閱讀 7,932評(píng)論 1 143
  • 簡(jiǎn)介 Java NIO 是由 Java 1.4 引進(jìn)的異步 IO.Java NIO 由以下幾個(gè)核心部分組成: Ch...
    永順閱讀 1,855評(píng)論 0 15
  • 這兩天了解了一下關(guān)于NIO方面的知識(shí),網(wǎng)上關(guān)于這一塊的介紹只是介紹了一下基本用法,沒(méi)有系統(tǒng)的解釋NIO與阻塞、非阻...
    Ruheng閱讀 7,237評(píng)論 5 48
  • 前言: 之前的文章《Java文件IO常用歸納》主要寫(xiě)了Java 標(biāo)準(zhǔn)IO要注意的細(xì)節(jié)和技巧,由于網(wǎng)上各種學(xué)習(xí)途徑,...
    androidjp閱讀 3,235評(píng)論 0 22
  • CPP_Basic_Code_P6.1-PP6.11.9
    貼墻上的咖啡閱讀 526評(píng)論 0 1

友情鏈接更多精彩內(nèi)容