Java NIO 學習:通道(Channel)

  通道(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。這兩個類AbstractInterruptibleChannelAbstractSelectableChannel,它們分別爲可中斷的(interruptible)和可選擇的(selectable)的通道實現提供所需的經常使用方法socket

打開通道

  IO能夠分爲File I/O和Stream I/O,通道也能夠分爲文件(file)通道和套接字(socket)通道,最經常使用的分別是FileChannel類和三個socket通道類:SocketChannelServerSocketChannelDatagramChannelspa

  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)

相關文章
相關標籤/搜索