1.介绍
NIO主要部分如下:
Channels
Buffers
Selectors
2.Channels主要包括:
FileChannel 从文件中读写数据
DatagramChannel 能通过UDP读写网络中的数据
SocketChannel 能通过TCP读写网络中的数据
ServerSocketChannel 可以监听新进来的TCP连接,对每一个新进来的连接都会创建一个SocketChannel
3.Buffer主要包括:
ByteBuffer
CharBuffer
DoubleBuffer
FloatBuffer
IntBuffer
LongBuffer
ShortBuffer
transferFrom()将数据从源通道传输到FileChannel中
transferTo()将数据从FileChannel传输到其他的channel中
Buffer使用步骤:
1.写入数据到Buffer
2.调用flip()方法
3.从Buffer中读取数据
4.调用clear()方法或者compact()方法
capacity是Buffer的容量
position是当前读写的位置
limit在写模式下等于capacity,在读模式下表示能读取的有效长度
创建ByteBuffer
ByteBuffer buf = ByteBuffer.allocate(1024);
flip()方法将Buffer从写模式切换到读模式
Buffer.rewind()将position设回0
clear()方法position将被设回0,limit被设置成 capacity的值
compact()方法将所有未读的数据拷贝到Buffer起始处
equals()和compareTo()方法比较两个Buffer
4.Scattering Reads/Gathering Writes
Scattering Reads是指数据从一个channel读取到多个buffer中
Gathering Writes是指数据从多个buffer写入到同一个channel
5.Selector
创建Selector selector = Selector.open()
注册通道
channel.configureBlocking(false);
channel.register(selector,Selectionkey.OP_READ)
NIO主要部分如下:
Channels
Buffers
Selectors
2.Channels主要包括:
FileChannel 从文件中读写数据
DatagramChannel 能通过UDP读写网络中的数据
SocketChannel 能通过TCP读写网络中的数据
ServerSocketChannel 可以监听新进来的TCP连接,对每一个新进来的连接都会创建一个SocketChannel
3.Buffer主要包括:
ByteBuffer
CharBuffer
DoubleBuffer
FloatBuffer
IntBuffer
LongBuffer
ShortBuffer
transferFrom()将数据从源通道传输到FileChannel中
transferTo()将数据从FileChannel传输到其他的channel中
Buffer使用步骤:
1.写入数据到Buffer
2.调用flip()方法
3.从Buffer中读取数据
4.调用clear()方法或者compact()方法
capacity是Buffer的容量
position是当前读写的位置
limit在写模式下等于capacity,在读模式下表示能读取的有效长度
创建ByteBuffer
ByteBuffer buf = ByteBuffer.allocate(1024);
flip()方法将Buffer从写模式切换到读模式
Buffer.rewind()将position设回0
clear()方法position将被设回0,limit被设置成 capacity的值
compact()方法将所有未读的数据拷贝到Buffer起始处
equals()和compareTo()方法比较两个Buffer
4.Scattering Reads/Gathering Writes
Scattering Reads是指数据从一个channel读取到多个buffer中
Gathering Writes是指数据从多个buffer写入到同一个channel
5.Selector
创建Selector selector = Selector.open()
注册通道
channel.configureBlocking(false);
channel.register(selector,Selectionkey.OP_READ)
6.实例
import java.io.*;
import java.nio.*;
import java.nio.channels.*;
import java.nio.channels.spi.*;
import java.net.*;
import java.util.*;
/**
*
* @author Administrator
* @version
*/
public class NBTest {
/** Creates new NBTest */
public NBTest()
{
}
public void startServer() throws Exception
{
int channels = 0;
int nKeys = 0;
int currentSelector = 0;
//使用Selector
Selector selector = Selector.open();
//建立Channel 并绑定到9000端口
ServerSocketChannel ssc = ServerSocketChannel.open();
InetSocketAddress address = new InetSocketAddress(InetAddress.getLocalHost(),9000);
ssc.socket().bind(address);
//使设定non-blocking的方式。
ssc.configureBlocking(false);
//向Selector注册Channel及我们有兴趣的事件
SelectionKey s = ssc.register(selector, SelectionKey.OP_ACCEPT);
printKeyInfo(s);
while(true) //不断的轮询
{
debug("NBTest: Starting select");
//Selector通过select方法通知我们我们感兴趣的事件发生了。
nKeys = selector.select();
//如果有我们注册的事情发生了,它的传回值就会大于0
if(nKeys > 0)
{
debug("NBTest: Number of keys after select operation: " +nKeys);
//Selector传回一组SelectionKeys
//我们从这些key中的channel()方法中取得我们刚刚注册的channel。
Set selectedKeys = selector.selectedKeys();
Iterator i = selectedKeys.iterator();
while(i.hasNext())
{
s = (SelectionKey) i.next();
printKeyInfo(s);
debug("NBTest: Nr Keys in selector: " +selector.keys().size());
//一个key被处理完成后,就都被从就绪关键字(ready keys)列表中除去
i.remove();
if(s.isAcceptable())
{
// 从channel()中取得我们刚刚注册的channel。
Socket socket = ((ServerSocketChannel)s.channel()).accept().socket();
SocketChannel sc = socket.getChannel();
sc.configureBlocking(false);
sc.register(selector, SelectionKey.OP_READ |SelectionKey.OP_WRITE);
System.out.println(++channels);
}
else
{
debug("NBTest: Channel not acceptable");
}
}
}
else
{
debug("NBTest: Select finished without any keys.");
}
}
}
private static void debug(String s)
{
System.out.println(s);
}
private static void printKeyInfo(SelectionKey sk)
{
String s = new String();
s = "Att: " + (sk.attachment() == null ? "no" : "yes");
s += ", Read: " + sk.isReadable();
s += ", Acpt: " + sk.isAcceptable();
s += ", Cnct: " + sk.isConnectable();
s += ", Wrt: " + sk.isWritable();
s += ", Valid: " + sk.isValid();
s += ", Ops: " + sk.interestOps();
debug(s);
}
/**
* @param args the command line arguments
*/
public static void main (String args[])
{
NBTest nbTest = new NBTest();
try
{
nbTest.startServer();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}