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)

相关文章
相关标签/搜索