java NIO是由下有下面几个核心组件组成
- Channels
- Buffers
- Selectors
Channels and Buffer
在NIO中,所有的io都起始于Channel,Channel类似与流,可以读到Buffer中,也可以从Buffer中写入。
这里有些例子,是Channel继承类:
- FileChannel
- DatagramChannel
- SocketChannel
- ServerSocketChannel
这些例子覆盖了UDP+TCP,网络IO,文件IO
还有些平时用的Buffer继承类
- ByteBuffer
- CharBuffer
- DoubleBuffer
- FloatBuffer
- IntBuffer
- LongBuffer
- ShortBuffer
- MappedByteBuffer
Selectors
一个线程只能有一个Selector,但Selector可以处理多个Channels
一个例子用FileChannel把数据放入Buffer中
RandomAccessFile afile = new RandomAccessFile("home/mine.txt","rw");
FileChannel inchannel = afile.getChannel();
ByteBuffer buffer = ByteBuffer.allocate(48);
int bytesRead = inChannel.read(buffer);
while(bytesRead !=-1){
System.out.println("Read"+bytesRead);
buffer.flip()//将buffer转换为读状态
while(buffer.hasRemaining()){
System.out.print((char)buffer.get());
}
buffer.clear();
bytesRead = inChannel.read(buffer);
}
afile.close
Buffer基础的用法
- 先把Channel中的数据写入Buffer中
- 在用buffer.flip()方法
- 再从buffer中读出数据
- 在用buffer.clear()方法
Buffer有三个重要的属性
- 初始的大小(Capacity)
- 位置(Position)
- 限制大小(limit)
限制数量和位置取决于Buffer是读还是写模式,出事的数量不管哪种模式都一样
Capacity
是Buffer中的固定的大小,你可以写入数据,一旦Buffer满了,在你写入更多数据之前需要把它清空
Position
当你写入数据时,你肯定正在写入Buffer的一个明确的位置上,初始时Position是0,但写入了数据后,数据会插入到这个位置,Position也会到下一个位置,position最多到Capacity-1,
Limit
在写模式下,Limit决定了你能写到Buffer中的数量,在读模式下,Limit决定了你能从Buffer中读的数量
为了获得Buffer对象你必须先分配给它内存大小,每个Buffer class都有allocate()method
下面是两个例子
ByteBuffer buf = ByteBuffer.allocate(48);
CharBuffer buf = CharBuffer.allocate(1024);
写数据到Buffer
- 从Channel中写入数据到Buffer
- 直接把数据写入Buffer
int bytesRead = inChannel.read(buffer);
buffer.put(127);
flip()
filp方法将buffer从写模式转为读模式,把position设为0,且将写模式下的position变成读模式下的limit ———-从Buffer中读数据
- 从Buffer中读数据到Channel
- 直接从Buffer中读数据
int bytesWritten = inChannel.write(buf);
byte aByte = buf.get();
rewind()
可以从新读buffer的数据,把position设为0。limit不改变
clear() 和compact()
一旦你读完了Buffer数据,你必须让Buffer在一次做好写准备,你可以调用clear()或compact()
调用clear(),position被设为0,limit被设为capacity,当你用了clear(),即使buffer中有你没读的数据,你也不知道他是不是没读。如果你需要之后读它你就需要用compact(),他会复制所有没读到的数据到Buffer的前面位置
mark()和reset()
mark()会记录下position
buffer.mark();
buffer.reset();
equals
两个Buffer相同当
- 有相同的类型
- 一样的大小
- Buffer中的数据一样