NIO核心概念和demo
参考 :https://wiki.jikexueyuan.com/project/java-nio-zh/java-nio-tutorial.html
SocketChannel
建立一个SocketChannel连接 open()
关闭一个SocketChannel连接 close()
从SocketChannel中读数据 read()
向SocketChannel写数据 write()
非阻塞模式
connect()
ServerSocketChannel
打开ServerSocketChannel open
关闭ServerSocketChannel close
监听链接 accept
非阻塞模式 serverSocketChannel.configureBlocking(false)
Selector
SelectorKey
- SelectionKey.OP_CONNECT
- SelectionKey.OP_ACCEPT
- SelectionKey.OP_READ
- SelectionKey.OP_WRITE
Buffer
ByteBuffer CharBuffer DoubleBuffer FloatBuffer IntBuffer LongBuffer ShortBuffer
RandomAccessFile aFile = new RandomAccessFile("data/nio-data.txt", "rw"); FileChannel inChannel = aFile.getChannel(); ByteBuffer buf = ByteBuffer.allocate(48); int bytesRead = inChannel.read(buf); while (bytesRead != -1) { System.out.println("Read " + bytesRead); buf.flip(); while(buf.hasRemaining()){ System.out.print((char) buf.get()); } buf.clear(); bytesRead = inChannel.read(buf); } aFile.close();
利用Buffer读写数据,通常遵循四个步骤:
- 把数据写入buffer;
- 调用flip; 把buffer从写模式调整为读模式
- 从Buffer中读取数据;
- 调用buffer.clear()或者buffer.compact() ;清空buffer
一个Buffer有三个属性是必须掌握的,分别是:
- capacity容量
- position位置
- limit限制
Channel
- FileChannel
- DatagramChannel
- SocketChannel
- ServerSocketChannel
public class IoServer { private int port =8080; private Selector selector; private ByteBuffer buffer = ByteBuffer.allocate(1024); public IoServer(int port){ try { this.port = port; ServerSocketChannel server = ServerSocketChannel.open(); server.bind(new InetSocketAddress(this.port)); //兼容BIO server.configureBlocking(false);//设置之后为非阻塞 selector = Selector.open(); server.register(selector, SelectionKey.OP_ACCEPT); } catch (IOException e) { e.printStackTrace(); } } public void listen(){ System.out.println("listen on " + this.port); while (true){ try { selector.select(); Set<SelectionKey> keys = selector.selectedKeys(); Iterator<SelectionKey> iterator = keys.iterator(); while (iterator.hasNext()){ SelectionKey key = iterator.next(); iterator.remove(); process(key); } } catch (IOException e) { e.printStackTrace(); } } } private void process(SelectionKey key) throws IOException { if(key.isAcceptable()){ ServerSocketChannel server = (ServerSocketChannel) key.channel(); //非阻塞 SocketChannel channel = server.accept(); channel.configureBlocking(false); key = channel.register(selector, SelectionKey.OP_READ); }else if(key.isReadable()){ // }else if (key.isWritable()){ // } } public static void main(String[] args) { new IoServer(8080).listen(); }