Java NIO:NIO概述

来源:http://www.cnblogs.com/samjustin/archive/2016/08/17/5780263.html
-Advertisement-
Play Games

Java NIO:NIO概述 在上一篇博文中講述了幾種IO模型,現在我們開始進入Java NIO編程主題。NIO是Java 4裡面提供的新的API,目的是用來解決傳統IO的問題。本文下麵分別從Java NIO的幾個基礎概念介紹起。 以下是本文的目錄大綱: 一.NIO中的幾個基礎概念 二.Channe ...


Java NIO:NIO概述

  在上一篇博文中講述了幾種IO模型,現在我們開始進入Java NIO編程主題。NIO是Java 4裡面提供的新的API,目的是用來解決傳統IO的問題。本文下麵分別從Java NIO的幾個基礎概念介紹起。

  以下是本文的目錄大綱:

  一.NIO中的幾個基礎概念

  二.Channel

  三.Buffer

  四.Selector

  若有不正之處,請多多諒解並歡迎批評指正。

  請尊重作者勞動成果,轉載請標明原文鏈接:

   http://www.cnblogs.com/dolphin0520/p/3919162.html

一.NIO中的幾個基礎概念

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

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

1 2 3 4 5 6 7 8 9 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同傳統IO中的Stream來類比,但是要註意,傳統IO中,Stream是單向的,比如InputStream只能進行讀取操作,OutputStream只能進行寫操作。而Channel是雙向的,既可用來進行讀操作,又可用來進行寫操作。

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

  下麵介紹一下NIO中最核心的一個東西:Selector。可以說它是NIO中最關鍵的一個部分,Selector的作用就是用來輪詢每個註冊的Channel,一旦發現Channel有註冊的事件發生,便獲取事件然後進行處理。

  比如看下麵的這個例子:

   

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

二.Channel

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

  以下是常用的幾種通道:

  • FileChannel
  • SocketChanel
  • ServerSocketChannel
  • DatagramChannel

  通過使用FileChannel可以從文件讀或者向文件寫入數據;通過SocketChannel,以TCP來向網路連接的兩端讀寫數據;通過ServerSocketChanel能夠監聽客戶端發起的TCP連接,併為每個TCP連接創建一個新的SocketChannel來進行數據讀寫;通過DatagramChannel,以UDP協議來向網路連接的兩端讀寫數據。

  下麵給出通過FileChannel來向文件中寫入數據的一個例子:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 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,故名思意,緩衝區,實際上是一個容器,是一個連續數組。Channel提供從文件、網路讀取數據的渠道,但是讀取或寫入的數據都必須經由Buffer。具體看下麵這張圖就理解了:

  上面的圖描述了從一個客戶端向服務端發送數據,然後服務端接收數據的過程。客戶端發送數據時,必須先將數據存入Buffer中,然後將Buffer中的內容寫入通道。服務端這邊接收數據必須通過Channel將數據讀入到Buffer中,然後再從Buffer中取出數據來處理。

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

  • ByteBuffer
  • IntBuffer
  • CharBuffer
  • LongBuffer
  • DoubleBuffer
  • FloatBuffer
  • ShortBuffer

  如果是對於文件讀寫,上面幾種Buffer都可能會用到。但是對於網路讀寫來說,用的最多的是ByteBuffer。

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

四.Selector

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

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

  關於Selector類的具體使用將在後續文章中闡述。

  參考資料:

  http://blog.csdn.net/wuxianglong/article/details/6604817

  http://www.360doc.com/content/12/0515/11/1542811_211144310.shtml

  http://www.iteye.com/topic/834447

  http://weixiaolu.iteye.com/blog/1479656

  http://ifeve.com/overview/


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 最近新寫的程式要做beta測試,在做綠色版(免安裝版)時遇到了問題,vs2015做的項目本以為像之前的vs版本一樣把msvcrXXX.dll還有另外幾個運行時庫都放到exe旁邊即可,然並卵。。。,在win7的測試機上還會提示找不到這個dll:api-ms-win-crt-runtime-l1-1-0 ...
  • 這篇博客總結了1天,希望自己以後返回來看的時候理解更深刻,也希望可以起到幫助初學者的作用. 轉載請註明 出自 : "luogg的博客園" , 因為前不久偶然發現某網站直接複製粘貼我的博客,交談之後他們修改了出處. 封裝 一, 封裝的概念 1. 類可以看成一個封裝體,將對象的屬性和方法封裝到類中. 2 ...
  • 在開發過程當中需要用到配置信息,這些信息不能進行硬編碼,這時配置文件是一個比較好的方式,java提供了properties格式的文件,以鍵值對的方式保存信息,在讀取的時候通過鍵獲得鍵對應的值,spring提供了讀取properties文件的支持,下麵看具體的配置, 一、<context:proper ...
  • --> 斷點續傳: 就像迅雷下載文件一樣,停止下載或關閉程式,下次下載時是從上次下載的地方開始繼續進行,而不是重頭開始... --> RandomAccessFile --> pointer(文件指針) --> seek(移動文件指針) --> 斷點續傳 --> 通過複製來模擬簡單的斷點續傳... ...
  • 什麼是延遲載入? 延遲載入是指當應用程式想要從資料庫獲取對象時(在沒有設置lazy屬性值為false),Hibernate只是從資料庫獲取符合條件的對象的OId從而生成代理對象,並沒有載入出對象 訪問該對象的屬性時才會載入出相應的值。簡答來說就是儘可能的減少查詢的數據量。 如何配置延遲載入 在Hib... ...
  • 原文轉自 http://www.cnblogs.com/ldms/p/4565547.html Yii 有很多 extension 可以使用,在查看了 Yii 官網上提供的與 OAuth 相關的擴展後,發現了幾個 OAuth2 的客戶端擴展,但是並沒有找到可以作為 OAuth2 Server 的擴展 ...
  • 網站業務規模和訪問量的逐步發展,原本由單台伺服器、單個功能變數名稱的迷你網站架構已經無法滿足發展需要。 此時我們可能會購買更多伺服器,並且啟用多個二級子功能變數名稱以頻道化的方式,根據業務功能將網站分佈部署在獨立的伺服器上;或通過負載均衡技術 (如:DNS輪詢、Radware、F5、LVS等)讓多個頻道共用一組服務 ...
  • Hello World! ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...