1、Java NIO vs IO
- Java NIO和IO的不同之处
NIO | IO |
---|---|
面向缓冲区 | 面向流 |
no-blocking | blocking |
Selectors |
- 面向缓冲区 vs 面向流
面向流:从一个文件读取数据后,没有任何的缓存区域。而且每次读完以后都没法再次读取已经读过的内容。
面向缓冲区:有一个buffer区域专门用于存储读的数据内容。 - no-blocking vs blocking
blocking:准备读取的内容还没有准备好的时候,io线程会进入blocked状态。
no-blocking:准备读取的内容还没有准备好的时候,nio线程可以先去做其他事情。 - Selector
由于nio no-blocking的特性,我们可以使用selector,让一个线程去管理多个流。
2、Java NIO概述
Java NIO的三个核心组成:
- channel
- buffer
- selector
Channel and Buffer
Channels read data into Buffers, and Buffers write data into Channels.
Selector
我们可以通过Selector,让一个线程控制多个Channel。
4、Java NIO Channel
Channel和Stream的几点不同:
- Channel可以读,也可以写,而Stream只能读或者写;
- Channel通过Buffer来进行读写;
- Channel可以读写异步。
Channel的几种实现:
- FileChannel
- DatagramChannel
- SocketChannel
- ServerSocketChannel
Example:
5、Java NIO Buffer
Buffer的基本用法
- 将数据写入Buffer;
- 使用filp()方法,让Buffer进入可读状态;
- buffer.get()读取Buffer里面的数据;
- 使用clear()或者compact()将Buffer中的内容清除。//clear()将所有的数据清除,compact()将已读数据清除
//获取文件
RandomAccessFile accessFile = new RandomAccessFile("G:\\company\\homework\\day01\\Collections.txt", "rw");
//获取该文件的channel
FileChannel fileChannel = accessFile.getChannel();
//分配buffer
ByteBuffer byteBuffer = ByteBuffer.allocate(48);
/*
channel是从文件读取内容到buffer里的,所以用read。
*/
int byteRead = fileChannel.read(byteBuffer);
while(byteRead != -1) {
byteBuffer.flip();//ready for read
while(byteBuffer.hasRemaining()) {
System.out.print((char)byteBuffer.get());
}
byteBuffer.clear();
byteRead = fileChannel.read(byteBuffer);
}
accessFile.close();
Buffer Capacitry, Position, Limit
capacity:buffer的容量;
position:当buffer进行读写的时候,我们对buffer中的某个位置进行读写,position就是指向这个位置的指针;
limit:写模式的时候,limit = capacity;读模式的时候,limit等于写模式下最后position的位置。
Buffer类型
- ByteBuffer
- MappedByteBuffer
- CharBuffer
- DoubleBuffer
- FloatBuffer
- IntBuffer
- LongBuffer
- ShortBuffer
为Buffer分配内存空间
分配48个byte
ByteBuffer buf = ByteBuffer.allocate(48);
分配1024个character
CharBuffer buf = CharBuffer.allocate(1024);
向Buffer中写数据
- 从Channel中读取
- 使用put()
//从Channel中读取
int bytesRead = channel.read(buf);
//使用put()
buf.put(27);
flip()
让buffer从writing mode转换为reading mode。即
limit = position; position = 0;
从Buffer读取数据
- 从Channel读取
- 使用get()
//从Channel读取
int bytesWritten = channel.write(buf);
//使用get()
byte aByte = buf.get();