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