通道(Channel)用於在字節緩衝區(通道只能在字節緩衝區上操做)和位於通道另外一側的實體(一般是一個文件或套接字)之間有效地傳輸數據,而且通道每每是和操做系統的文件描述符(File Descriptor)和文件句柄(File Handle)對應的,能夠用最小的總開銷來訪問操做系統自己的I/O服務html
類圖結構以下所示java
基本的Channel接口源碼ios
package java.nio.channels; public interface Channel { public boolean isOpen( ); //通道是否打開 public void close( ) throws IOException; //關閉一個打開的通道 }
InterruptibleChannel是一個標記接口,標示該通道是能夠中斷的(Interruptible),若是鏈接可中斷通道的線程被中斷,那麼該通道會以特別的方式工做。大多數但非所有的通道都是能夠中斷的dom
類層次結構中有兩個類位於一個不一樣的包:java.nio.channels.spi。這兩個類AbstractInterruptibleChannel和AbstractSelectableChannel,它們分別爲可中斷的(interruptible)和可選擇的(selectable)的通道實現提供所需的經常使用方法socket
IO能夠分爲File I/O和Stream I/O,通道也能夠分爲文件(file)通道和套接字(socket)通道,最經常使用的分別是FileChannel類和三個socket通道類:SocketChannel、ServerSocketChannel和DatagramChannelspa
Socket通道有能夠直接建立新socket通道的工廠方法。可是一個FileChannel對象卻只能經過在一個打開的RandomAccessFile、FileInputStream或FileOutputStream對象上調用getChannel( )方法來獲取操作系統
package com.henrysun.javaSE.niostudy; import java.io.IOException; import java.io.RandomAccessFile; import java.net.InetSocketAddress; import java.nio.channels.DatagramChannel; import java.nio.channels.FileChannel; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; /** * 打開通道 */ public class ChannelOpen { /** * @param args * @throws IOException */ public static void main(String[] args) throws IOException { SocketChannel sc = SocketChannel.open(); sc.connect(new InetSocketAddress("somehost", 8080)); ServerSocketChannel ssc = ServerSocketChannel.open(); ssc.socket().bind(new InetSocketAddress(8090)); DatagramChannel dc = DatagramChannel.open(); RandomAccessFile raf = new RandomAccessFile("somefile", "r"); FileChannel fc = raf.getChannel(); } }
上面的類圖結構,大部分零亂部分移除能夠獲得以下的UML圖.net
public interface ReadableByteChannel extends Channel { public int read(ByteBuffer dst) throws IOException; } public interface WritableByteChannel extends Channel { public int write(ByteBuffer src) throws IOException; } public interface ByteChannel extends ReadableByteChannel, WritableByteChannel { }
通道能夠是單向的或者雙向的,一個channel類可能實現定義read( )方法的ReadableByteChannel接口,而另外一個channel類也許實現WritableByteChannel接口以提供write( )方法。實現這兩種接口其中之一的類都只能在一個方向上傳輸數據。若是一個類同時實現這兩個接口,那麼它能夠雙向傳輸數據。這對於sockets不是問題,由於它一直是雙向的,可是從FileInputStream對象的getChannel( )方法獲取的FileChannel對象是隻讀的,由於FileInputStream對象老是以read-only的權限打開文件,儘管FileChannel實現了ByteChannel接口。調用write( )方法將拋出未經檢查的NonWritableChannelException異常線程
通道能夠以阻塞和非阻塞模式運行。非阻塞模式的通道永遠不會讓調用的線程休眠。請求的操做要麼當即完成,要麼返回一個結果代表未進行任何操做。只有面向流的(stream-oriented)的通道,如sockets和pipes才能使用非阻塞模式code
注:socket通道類從SelectableChannel引伸而來。從SelectableChannel引伸而來的類能夠和支持有條件的選擇(readiness selectio)的選擇器(Selectors)一塊兒使用。將非阻塞I/O和選擇器組合起來可使您的程序利用多路複用I/O(multiplexed I/O)