Java NIO
2021-09-01 08:29:35 0 举报
AI智能生成
登录查看完整内容
Java NIO
作者其他创作
大纲/内容
Java NIO中的Buffer用于和NIO通道进行交互。如你所知,数据是从通道读入缓冲区,从缓冲区写入到通道中的。缓冲区本质上是一块可以写入数据,然后可以从中读取数据的内存。这块内存被包装成NIO Buffer对象,并提供了一组方法,用来方便的访问该块内存
ByteBuffer
CharBuffer
DoubleBuffer
FloatBuffer
IntBuffer
LongBuffer
ShortBuffer
类实现
作为一个内存块,Buffer有一个固定的大小值,也叫“capacity”.你只能往里写capacity个byte、long,char等类型。一旦Buffer满了,需要将其清空(通过读数据或者清除数据)才能继续写数据往里写数据
capacity
当读取数据时,也是从某个特定位置读。当将Buffer从写模式切换到读模式,position会被重置为0. 当从Buffer的position处读取数据时,position向前移动到下一个可读的位置
读
当你写数据到Buffer中时,position表示当前的位置。初始的position值为0.当一个byte、long等数据写到Buffer后, position会向前移动到下一个可插入数据的Buffer单元。position最大可为capacity – 1
写
position
当切换Buffer到读模式时, limit表示你最多能读到多少数据。因此,当切换Buffer到读模式时,limit会被设置成写模式下的position值。换句话说,你能读到之前写入的所有数据(limit被设置成已写数据的数量,这个值在写模式下就是position)
在写模式下,Buffer的limit表示你最多能往Buffer里写多少数据。 写模式下,limit等于Buffer的capacity
limit
三个属性
ByteBuffer.allocate(capacity);
创建
int bytesRead = inChannel.read(buf);
从Channel写入Buffer
buffer.put(value)
手动写数据到buffer
写数据
int bytesWritten = inChannel.write(buf);
从Buffer读取数据到Channel
byte aByte = buf.get();
使用get()方法从Buffer中读取数据
读数据
flip()
rewind()
一旦读完Buffer中的数据,需要让Buffer准备好再次被写入。可以通过clear()或compact()方法来完成
如果调用的是clear()方法,position将被设回0,limit被设置成 capacity的值。换句话说,Buffer 被清空了。Buffer中的数据并未清除,只是这些标记告诉我们可以从哪里开始往Buffer里写数据 如果Buffer中有一些未读的数据,调用clear()方法,数据将“被遗忘”,意味着不再有任何标记会告诉你哪些数据被读过,哪些还没有
clear()
compact()方法将所有未读的数据拷贝到Buffer起始处。然后将position设到最后一个未读元素正后面。limit属性依然像clear()方法一样,设置成capacity。现在Buffer准备好写数据了,但是不会覆盖未读的数据
compact()
clear()与compact()
可以使用equals()和compareTo()方法两个Buffer
当满足下列条件时,表示两个Buffer相等:1.有相同的类型(byte、char、int等)。2.Buffer中剩余的byte、char等的个数相等。3.Buffer中所有剩余的byte、char等都相同。equals只是比较Buffer的一部分,不是每一个在它里面的元素都比较。实际上,它只比较Buffer中的剩余元素
equals()
compareTo()方法比较两个Buffer的剩余元素(byte、char等), 如果满足下列条件,则认为一个Buffer“小于”另一个Buffer:1.第一个不相等的元素小于另一个Buffer中对应的元素 。2.所有元素都相等,但第一个Buffer比另一个先耗尽(第一个Buffer的元素个数比另一个少)
compareTo()
equals()与compareTo()
从Channel(译者注:Channel在中文经常翻译为通道)中读取或者写入到Channel的操作
从Channel中读取是指在读操作时将读取的数据写入多个buffer中。因此,Channel将从Channel中读取的数据“分散(scatter)”到多个Buffer中
scatter
写入Channel是指在写操作时将多个buffer的数据写入同一个Channel,因此,Channel 将多个Buffer中的数据“聚集(gather)”后发送到Channel
gather
scatter / gather经常用于需要将传输的数据分开处理的场合,例如传输一个由消息头和消息体组成的消息,你可能会将消息体和消息头分散到不同的buffer中,这样你可以方便的处理消息头和消息体
应用场景
scatter/gather
方法
Buffers
Selector(选择器)是Java NIO中能够检测一到多个NIO通道,并能够知晓通道是否为诸如读写事件做好准备的组件。这样,一个单独的线程可以管理多个channel,从而管理多个网络连接
Selector selector = Selector.open();
channel注册
Selectors
Channels
Java NIO的通道类似流,但又有些不同:既可以从通道中读取数据,又可以写数据到通道。但流的读写通常是单向的。通道可以异步地读写。通道中的数据总是要先读到一个Buffer,或者总是要从一个Buffer中写入
Java NIO中的FileChannel是一个连接到文件的通道。可以通过文件通道读写文件。FileChannel无法设置为非阻塞模式,它总是运行在阻塞模式下。
通过使用一个InputStream、OutputStream或RandomAccessFile来获取一个FileChannel实例
首先,分配一个Buffer。从FileChannel中读取的数据将被读到Buffer中。然后,调用FileChannel.read()方法。该方法将数据从FileChannel读取到Buffer中。read()方法返回的int值表示了有多少字节被读到了Buffer中。如果返回-1,表示到了文件末尾
使用FileChannel.write(buffer)方法向FileChannel写数据,该方法的参数是一个Buffer。FileChannel.write()是在while循环中调用的
channel.close();
关闭
FilChannel的transferFrom()方法可以将数据从源通道传输到FileChannel中
源Channel
src
从position处开始向目标文件写入数据
count表示最多传输的字节数。如果源通道的剩余空间小于 count 个字节,则所传输的字节数要小于请求的字节数
count
transferTo()方法将数据从FileChannel传输到其他的channel中
目标channel
target
获取FileChannel的当前位置
position()
设置FileChannel的当前位置
position(long pos)
返回该实例所关联文件的大小
size()
截取文件时,文件将中end后面的部分将被删除
truncate(long end)
将通道里尚未写入磁盘的数据强制写到磁盘上。出于性能方面的考虑,操作系统会将数据缓存在内存中,所以无法保证写入到FileChannel里的数据一定会即时写到磁盘上。要保证这一点,需要调用force()方法。force()方法有一个boolean类型的参数,指明是否同时将文件元数据(权限信息等)写到磁盘上。
force(boolean metaData)
FileChannel
DatagramChannel
SocketChannel
ServerSocketChannel
Java NIO
0 条评论
回复 删除
下一页