Socket套接字之间的连接过程分为三个步骤:
- 服务器监听
- 客户端请求
- 连接确认。
Java NIO的通道类似流,但又有些不同:
- 流只是在一个方向上移动(一个流必须是 InputStream 或者 OutputStream 的子类),而通道可以用于读、写或者同时用于读写,是全双工的。
- 通道可以异步地读写。
- 通道中的数据总是要先读到一个Buffer,或者总是要从一个Buffer中写入。
Buffer的理解
- position ,limit,capacity机制,读和写两种
- Buffer与Channel之间的读和写操作,分为一对一,一对多,多合一,三种方式。
- buffer.flip()切换到读模式。clear()方法会清空整个缓冲区。compact()方法只会清除已经读过的数据。
- buffer.marker(),buffer.reset()连用。通过调用Buffer.mark()方法,可以标记Buffer中的一个特定position。之后可以通过调用Buffer.reset()方法恢复到这个position。
- 写入Buffer(读取buffer类似)
- channel.read(buffer)
- buffer.put(byte b)
Channel的理解
这些是Java NIO中最重要的通道的实现:
- FileChannel。FileChannel实例的size()方法将返回该实例所关联文件的大小。FileChannel.force()方法将通道里尚未写入磁盘的数据强制写到磁盘上。出于性能方面的考虑,操作系统会将数据缓存在内存中,所以无法保证写入到FileChannel里的数据一定会即时写到磁盘上。要保证这一点,需要调用force()方法。
- DatagramChannel,面向UDP
- SocketChannel
- ServerSocketChannel
默认实现是阻塞式的,需要异步非阻塞式的,调用方法socketChannel.configureBlocking(false)
Selector的理解
Selctor的建立
Selector selector = Selector.open();
SelectionKey对象
- interest集合是你所选择的感兴趣的事件集合。int interestSet = selectionKey.interestOps();
有以下几个:
- SelectionKey.OP_CONNECT
- SelectionKey.OP_ACCEPT
- SelectionKey.OP_READ
- SelectionKey.OP_WRITE
- ready集合是通道已经准备就绪的操作的集合。int readySet = selectionKey.readyOps();。
- selectionKey.isAcceptable();
- selectionKey.isConnectable();
- selectionKey.isReadable();
- selectionKey.isWritable();
从SelectionKey访问Channel和Selector很简单。如下:
- Channel channel = selectionKey.channel();
- Selector selector = selectionKey.selector();
Pipe的理解
Pipe有一个source通道和一个sink通道。
创建
1 Pipe pipe = Pipe.open();
sink通道创建
Pipe.SinkChannel sinkChannel = pipe.sink();
source通道
Pipe.SourceChannel sourceChannel = pipe.source();
Java NIO和IO的主要区别
下表总结了Java NIO和IO之间的主要差别
- IO 面向流,阻塞IO
- NIO,面向缓冲, 非阻塞IO,选择器
Java IO 管道
一个线程通过PipedOutputStream写入的数据可以被另一个线程通过相关联的PipedInputStream读取出来。