溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java NIO知識點有哪些

發(fā)布時間:2022-01-05 09:54:56 來源:億速云 閱讀:144 作者:iii 欄目:大數(shù)據(jù)

本篇內容介紹了“Java NIO知識點有哪些”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

一.NIO中的幾個基礎概念

  在NIO中有幾個比較關鍵的概念:Channel(通道),Buffer(緩沖區(qū)),Selector(選擇器)。

  首先從Channel說起吧,通道,顧名思義,就是通向什么的道路,為某個提供了渠道。在傳統(tǒng)IO中,我們要讀取一個文件中的內容,通常是像下面這樣讀取的:

public class Test {    public static void main(String[] args) throws IOException  {        File file = new File("data.txt");        InputStream inputStream = new FileInputStream(file);        byte[] bytes = new byte[1024];        inputStream.read(bytes);        inputStream.close();    }  }

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

  因此可以將NIO 中的Channel同傳統(tǒng)IO中的Stream來類比,但是要注意,傳統(tǒng)IO中,Stream是單向的,比如InputStream只能進行讀取操作,OutputStream只能進行寫操作。而Channel是雙向的,既可用來進行讀操作,又可用來進行寫操作。

  Buffer(緩沖區(qū)),是NIO中非常重要的一個東西,在NIO中所有數(shù)據(jù)的讀和寫都離不開Buffer。比如上面的一段代碼中,讀取的數(shù)據(jù)時放在byte數(shù)組當中,而在NIO中,讀取的數(shù)據(jù)只能放在Buffer中。同樣地,寫入數(shù)據(jù)也是先寫入到Buffer中。

  下面介紹一下NIO中最核心的一個東西:Selector??梢哉f它是NIO中最關鍵的一個部分,Selector的作用就是用來輪詢每個注冊的Channel,一旦發(fā)現(xiàn)Channel有注冊的事件發(fā)生,便獲取事件然后進行處理。

  比如看下面的這個例子:

Java NIO知識點有哪些

  用單線程處理一個Selector,然后通過Selector.select()方法來獲取到達事件,在獲取了到達事件之后,就可以逐個地對這些事件進行響應處理。

二.Channel

  在前面已經(jīng)提到,Channel和傳統(tǒng)IO中的Stream很相似。雖然很相似,但是有很大的區(qū)別,主要區(qū)別為:通道是雙向的,通過一個Channel既可以進行讀,也可以進行寫;而Stream只能進行單向操作,通過一個Stream只能進行讀或者寫;

  以下是常用的幾種通道:

  • FileChannel

  • SocketChanel

  • ServerSocketChannel

  • DatagramChannel

  通過使用FileChannel可以從文件讀或者向文件寫入數(shù)據(jù);通過SocketChannel,以TCP來向網(wǎng)絡連接的兩端讀寫數(shù)據(jù);通過ServerSocketChanel能夠監(jiān)聽客戶端發(fā)起的TCP連接,并為每個TCP連接創(chuàng)建一個新的SocketChannel來進行數(shù)據(jù)讀寫;通過DatagramChannel,以UDP協(xié)議來向網(wǎng)絡連接的兩端讀寫數(shù)據(jù)。

  下面給出通過FileChannel來向文件中寫入數(shù)據(jù)的一個例子:

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

  Buffer,故名思意,緩沖區(qū),實際上是一個容器,是一個連續(xù)數(shù)組。Channel提供從文件、網(wǎng)絡讀取數(shù)據(jù)的渠道,但是讀取或寫入的數(shù)據(jù)都必須經(jīng)由Buffer。具體看下面這張圖就理解了:

Java NIO知識點有哪些

  上面的圖描述了從一個客戶端向服務端發(fā)送數(shù)據(jù),然后服務端接收數(shù)據(jù)的過程??蛻舳税l(fā)送數(shù)據(jù)時,必須先將數(shù)據(jù)存入Buffer中,然后將Buffer中的內容寫入通道。服務端這邊接收數(shù)據(jù)必須通過Channel將數(shù)據(jù)讀入到Buffer中,然后再從Buffer中取出數(shù)據(jù)來處理。

  在NIO中,Buffer是一個頂層父類,它是一個抽象類,常用的Buffer的子類有:

  • ByteBuffer

  • IntBuffer

  • CharBuffer

  • LongBuffer

  • DoubleBuffer

  • FloatBuffer

  • ShortBuffer

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

  關于Buffer的具體使用以及它的limit、posiion和capacity這幾個屬性的理解在下一篇文章中講述。

四.Selector

  Selector類是NIO的核心類,Selector能夠檢測多個注冊的通道上是否有事件發(fā)生,如果有事件發(fā)生,便獲取事件然后針對每個事件進行相應的響應處理。這樣一來,只是用一個單線程就可以管理多個通道,也就是管理多個連接。這樣使得只有在連接真正有讀寫事件發(fā)生時,才會調用函數(shù)來進行讀寫,就大大地減少了系統(tǒng)開銷,并且不必為每個連接都創(chuàng)建一個線程,不用去維護多個線程,并且避免了多線程之間的上下文切換導致的開銷。

  與Selector有關的一個關鍵類是SelectionKey,一個SelectionKey表示一個到達的事件,這2個類構成了服務端處理業(yè)務的關鍵邏輯。

“Java NIO知識點有哪些”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關的知識可以關注億速云網(wǎng)站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內容。

AI