在nio中是面向块(block)或者缓冲区(buffer)编程的,
selector(是一个线程) :这个线程可以对channel进行来回切换(通过事件来决定)
channel (可以将nio中的channel理解成io中的stream):指的是可以向其中写入对象或者读取对象,
但是所有数据的读写都是通过buffer来进行的,永远不会出现直接向channel写如数据的情况或者从Channel读取数据的情况,与stream不同的是channel是双向的,一个流只可能是InputStream或是OutputStream,channel打开后则可以进行读取和写入
buffer:buffer本身就是一块内存,底层实现上实际是个数组,数据的读写都是通过buffer来实现的,在nio中读取数据,例如读取文件,必须先将数据从channel中读取到buffer中,再从buffer中读取出来,
除了数组之外,buffer还提供了对于数据的结构化访问方式,并且可以追踪到系统的读写过程.
java中的8种原生类型(除了booleanBuffer)都有各自的buffer类型.如IntBuffer,LongBuffer,CharBuffer 等等
public class NioTest1 {
public static void main(String[] args) {
IntBuffer buffer =IntBuffer.allocate(20);
for (int i = 0; i <buffer.capacity() ; i++) {
int randomNumber=new SecureRandom().nextInt(20);
buffer.put(randomNumber);
}
//nio中一个buffer既可以是读也可以是可写的,通过filp()方法进行读写的切换
buffer.flip();
while (buffer.hasRemaining()){
System.out.println(buffer.get());
}
}
}
关于nio buffer中3个重要状态属性的含义:positon,limit与capacity
postition:将要被读或者写的下一个元素
A buffer's position is the index of the next element to be read or written. A buffer's position is never negative and is never greater than its limit.
limit: buffer中的最后一个元素的下一个元素A buffer's limit is the index of the first element that should not be read or written. A buffer's limit is never negative and is never greater than its capacity.
capacity: 指向当前buffer中的最后一个元素的下一个元素A buffer's capacity is the number of elements it contains. The capacity of a buffer is never negative and never changes.
**调用flip()方法之后** postition会变为第一个元素 变为0 limit会变为当前buffer中最后一个元素的下一个元素 limit=原buffer **再次调用flip()方法之后** postition变为0, limit变为原postition **0<=mark<=position<=limit**long address;
再谈ByteBuffer
byteBuffer的创建方式:
- allocate(int capacity)方法
//间接缓冲区
public static ByteBuffer allocate(int capacity) {
if (capacity < 0)
throw new IllegalArgumentException();
return new HeapByteBuffer(capacity, capacity);
}
- wrap(byte[] array, int offset, int length)
不能通过修改数组的内容来修改bytebuffer
public static ByteBuffer wrap(byte[] array,
int offset, int length)
{
try {
return new HeapByteBuffer(array, offset, length);
} catch (IllegalArgumentException x) {
throw new IndexOutOfBoundsException();
}
}
//直接缓冲区
public static ByteBuffer allocateDirect(int capacity) {
return new DirectByteBuffer(capacity);
}
MappedByteBuffer
将文件的修改直接在内存中进行
Selector
/**
-
A multiplexor of {@link SelectableChannel} objects.
-
A selector may be created by invoking the {@link #open open} method of
-
this class, which will use the system’s default {@link
-
java.nio.channels.spi.SelectorProvider selector provider} to
-
create a new selector. A selector may also be created by invoking the
-
{@link java.nio.channels.spi.SelectorProvider#openSelector openSelector}
-
method of a custom selector provider. A selector remains open until it is
-
closed via its {@link #close close} method.
-
A selectable channel's registration with a selector is represented by a
-
{@link SelectionKey} object. A selector maintains three sets of selection
-
keys:
-
SelectionKey: selector和channel的连接
-
keyset: selector和channel注册连接之后的信息全部保存在keyset中,
-
//keyset 包含所有的集合
The key set contains the keys representing the current channel registrations of this selector. This set is returned by the {@link #keys() keys} method.
- //selected-key set 感兴趣的集合
The selected-key set is the set of keys such that each key's channel was detected to be ready for at least one of the operations identified in the key's interest set during a prior selection operation. This set is returned by the {@link #selectedKeys() selectedKeys} method. The selected-key set is always a subset of the key set.
//cancelled-key 被取消了的集
The cancelled-key set is the set of keys that have been cancelled but whose channels have not yet been deregistered. This set is not directly accessible. The cancelled-key set is always a subset of the key set.
当一个事件发生了,感兴趣的key才会进入到集合当中,