Java NIO Channel
- Channel 实施
- 基本的Channel实例
Java NIO Channel和streams的区别
- 你可以在Channel中读取和写入.Streams只能读或者写
- Channels可以进行读写的异步
- Channels通常是从Buffer中读取或者是写入到Buffer中
需要注意的是,你的数据从channel读取到buffer中,写入数据是也是通过buffer
Channel Implementations
这里有一些重要的Channel Implementation在Java NIO中:
* FileChannel:从文件中读写数据
* DatagramChannel:从UDP中读写数据
* SocketChannel:从TCP中读写数据
* ServerSocketChannel:允许你监听来自TCP的连接,就如同web服务器一样。对于每一个来的连接会创建一个SocketChannel
Channel实例(FileChannel)
Java NIO Buffer
- 基本Buffer使用
- Buffer容量,位置和限制
- Buffer类型
- 申请Buffer
- 将数据写入到Buffer中
- flip()
- 从Buffer中获取数据
- rewind()
- clear() and compact()
- mark() and reset()
- equals() and compareTo()
Java NIO Buffers被用于和NIO Channel进行交互。正如你所知道的那样,数据从channels中读取到buffer中,或者数据以buffer的形式传给channels
一个Buffer本质上上是一个你只能写的内存块,之后你能再次读取。这个内存快包装到一个NIO Buffer对象中,这样能通过一些已经提供过的方法让我们更方便的操作内存块
基本的Buffer使用
使用Buffer的写和读数据操作通常都是如下的4个步骤:
- 将数据写入到buffer中
- 调用buffer.flip()函数
- 将数据从Buffer中读取
- 调用buffer.clear()或者时buffer.compact()函数
当你将数据写入到buffer中,buffer会跟踪你写了多少数据。一旦你需要读取数据的时候,你首先需要将buffer的写模式改变成读模式,调用flip()函数。在读模式,buffer允许你读取你之前所写入的所有数据
一旦你读取了所有的数据,你需要清除你的buffer,为了是让它再一次的能写。有两种方法可以做到这一点,一个是调用clear()函数或者是compact()函数。clear()函数清除全部的buffer。compact()函数只会清除你刚刚读的buffer。任何没有被读的buffer都会被新写入的数据冲掉
Buffer容量,位置和限制
一个buffer的本质是一个内存块,并且你能够写数据,在写入数据后可以通过buffer来进行读取。
这个内存块通过NIO Buffer对象进行修饰,提供方便的方法可以操纵内存。
一个Buffer可以有3个属性你应该熟悉的
- 容量
- 位置
- 限制
容量和位置的概念建立于Buffer是读模式还是写模式。容量对于读模式和写模式都是一样的
Capacity
对于一个内存块,一个Buffer有一个确切的体积,所以叫做容量,你能往里面写入bytes, longs, chars等。一旦buffer满了,你需要清空它,这样你才能写入更多的数据
Position
当你向Buffer写数据的时候,你在一个确切的位置上。开始时候的位置是0.当一个数据类型如byte,long等类型被写入到Buffer中,这时候指针就会指向下一个位置等待插入,Position的位置是容量-1
当你从Buffer众读取数据的时候,你仍需要一个给定的位置。当你使用filp将一个Buffer从写模式切换到读模式的时候,position将会重置到0。当你读取数据的时候position会自动的指向下一个你要读取的位置
Limit
在写模式,限制是限制你能往buffer中写入多少数据。在写模式Limit相当于容量的大小
在读模式的时候,意味着你能从buffer中读取多少数据。因此当buffer转换成读模式的时候,limit限制到了写入的位置,这样你能读取刚刚写入的数据
Buffer类型
Java NIO有如下几种Buffer类型:
- ByteBuffer
- MappedByteBuffer
- CharBuffer
- DoubleBuffer
- FloatBuffer
- IntBuffer
- LongBuffer
- ShortBuffer
正如你所看到的,这些Buffer类型代表着不同的数据种类,换句话说,这让你能够操作char, short, int, long, float或者是double
申请Buffer
为了获得一个buffer对象,你必须首先申请它,每一个Buffer类都有一个Allocate函数,通过这个函数你能申请到Buffer
将数据写入到Buffer中
你可以通过两种方式将数据写入到Buffer中去
- 通过Channel将数据写入到Buffer中去
- 通过Buffer的put()方法
filp()
flip()函数能够将Buffer的写模式转换为读模式。调用filp()函数能够将position设置到0
从Buffer中获取数据
这里有两种从Buffer中读取数据的方法:
- 从Channel中读取数据
- 通过buffer的get方法获取数据
rewind()
Buffer.rewind()方法允许将position的位置设置到0,你可以重新读取数据