#NIO
---
Java NIO(New IO)是一個可以替代標準Java IO API的IO API(從Java1.4開始),Java NIO提供了與標準IO不同的IO工作方式。
###Java NIO: Channels and Buffers(通道和緩沖區)
標準的俄IO基于字節流和字符流進行操作的,而NIO是基于通道(Channel)和緩沖區(Buffer)進行操作,數據總是從通道讀取到緩沖區中,或者從緩沖區寫入通道也類似。
###Java NIO: Non-blocking IO(非阻塞IO)
Java NIO可以讓你非阻塞的使用IO,例如:當線程從通道讀取數據到緩沖區時,線程還是進行其他事情。當數據被寫入到緩沖區時,線程可以繼續處理它。從緩沖區寫入通道也類似。
###Java NIO: Selectors(選擇器)
Java NIO引入了選擇器的概念,選擇器用于監聽多個通道的事件(比如:連接打開,數據到達)。因此,單個的線程可以監聽多個數據通道。
NIO由以下核心部分組成:
* Channels
* Buffers
* Selectors
**Channel和Buffer**
基本上,所有的IO和NIO都從一個Channel開始。Channel有點像流。數據可以從Channel讀到Buffer中,也可以從Buffer寫到Channel中

Channel的實現
* FileChannel
* DatagramChannel
* SocketChannel
* ServerSocketChannel
這些通道涵蓋了UDP和TCP網絡IO,以及文件IO。
以下是Java NIO里關鍵的Buffer實現
* ByteBuffer
* CharBuffer
* DoubleBuffer
* FloatBuffer
* IntBuffer
* LongBuffer
* ShortBuffer
這些Buffer覆蓋了你能通過IO發送的基本數據類型:byte,short,int,long,float,double和char
Java NIO還有個MappedByteBuffer,用于表示內存映射文件。
**Selextor**
Selector允許單線程處理多個Channel。如果你的應用打開了多個連接(通道),但每一個連接的流量都很低,使用Selector就會很方便。
例如,在一個聊天服務器中
這是在一個單線程中使用一個Selector處理3個Channel的圖示:

要使用Selector,得向Selector注冊Channel,然后調用它的select()方法。這個方法會一直阻塞到某個注冊的通道有事件就緒。一旦這個方法返回,線程就可以處理這些事件,事件的例子有如新連接進來,數據接送等。
##Channel
---
Java NIO的通道類似流,但又有些不同:
* 既可以從通道中讀取數據,又可以寫數據到通道。但流的讀寫通常是單向的。
* 通道可以異步的讀寫。
* 通道的數據總是要先讀到一個Buffer,或者總要從一個Buffer中寫入。
正如上面所說,從通道讀取數據到緩沖區,從緩沖區寫入數據到通道。
**Channel的實現**
* FileChannel 從文件中讀取數據
* DataChannel 能通過UDP讀寫網絡中的數據
* SocketChannel 能通過TCP讀寫網絡中的數據
* ServerSocketChannel 可以監聽新進來的TCP連接,像Web服務器那樣。對每一個新進來的連接都會創建一個SocketChannel
基本的Channel示例
下面是一個使用FileChannel讀取數據到Buffer中的示例
```
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();
```
注意 buf.flip() 的調用,首先讀取數據到Buffer,然后反轉Buffer,接著再從Buffer中讀取數據。
##Buffer
Java NIO中的Buffer用于和NIO通道進行交互。如你所知,數據是從通道讀入緩沖區,從緩沖區寫入到通道中的。
緩沖區本質是一塊可以寫入數據,然后可以從中讀取數據的內存。這塊內存被包裝成NIO Buffer對象,并提供了一組方法,用來方便的訪問這塊內存。
**Buffer的基本用法**
使用Buffer讀寫數據一般遵循以下四個步驟:
1. 寫入數據到Buffer
2. 調用flip()方法
3. 從Buffer中讀取數據
4. 調用clear()方法或者compact()方法
- JavaSE(Java基礎)
- Java基礎知識
- Java中的內存泄漏
- String源碼分析
- Java集合結構
- ArrayList源碼剖析
- HashMap源碼剖析
- Hashtable簡介
- Vector源碼剖析
- LinkedHashMap簡介
- LinkedList簡介
- JVM(Java虛擬機)
- JVM基礎知識
- JVM類加載機制
- Java內存區域與內存溢出
- 垃圾回收算法
- Java并發(JavaConcurrent)
- Java并發基礎知識
- 生產者和消費者問題
- Thread和Runnable實現多線程的區別
- 線程中斷
- 守護線程與阻塞線程的情況
- Synchronized
- 多線程環境中安全使用集合API
- 實現內存可見的兩種方法比較:加鎖和volatile變量
- 死鎖
- 可重入內置鎖
- 使用wait/notify/notifyAll實現線程間通信
- NIO
- 數據結構(DataStructure)
- 數組
- 棧和隊列
- Algorithm(算法)
- 排序
- 選擇排序
- 冒泡排序
- 快速排序
- 歸并排序
- 查找
- 順序查找
- 折半查找
- Network(網絡)
- TCP/UDP
- HTTP
- Socket
- OperatingSystem(操作系統)
- Linux系統的IPC
- android中常用設計模式
- 面向對象六大原則
- 單例模式
- Builder模式
- 原型模式
- 簡單工廠
- 策略模式
- 責任鏈模式
- 觀察者模式
- 代理模式
- 適配器模式
- 外觀模式
- Android(安卓面試點)
- Android基礎知識
- Android內存泄漏總結
- Handler內存泄漏分析及解決
- Android性能優化
- ListView詳解
- RecyclerView和ListView的異同
- AsyncTask源碼分析
- 插件化技術
- 自定義控件
- ANR問題
- Art和Dalvik的區別
- Android關于OOM的解決方案
- Fragment
- SurfaceView
- Android幾種進程
- APP啟動過程
- 圖片三級緩存
- Bitmap的分析與使用
- 熱修復的原理
- AIDL
- Binder機制
- Zygote和System進程的啟動過程
- Android中的MVC,MVP和MVVM
- MVP
- Android開機過程
- EventBus用法詳解
- 查漏補缺
- Git操作