首页 > 编程知识 正文

java bytebuffer,bytebuffer写文件

时间:2023-05-05 00:40:46 阅读:134940 作者:1865

ByteBuffer详细信息ByteBuffer详细信息概述ByteBuffer属性capacitylimitposition暖大豆ByteBuffer方法allocate () order ) (put ) (flip ) (array ) ge

概要

ByteBuffer顾名思义是byte缓冲区,实际上底层就是byte[ ]ByteBuffer有HeapByteBuffer和DirectByteBuffer两种。 我们知道ByteBuffer实际上是一块内存。 前者是属于JVM的内存,后者是申请的JVM以外的内存,即运行JVM的系统的内存。 没有特殊的需求一般都用HeapByteBuffer吧(大概毕竟我也没有工作,不知道水蜜桃的世界)。

ByteBuffer属性capacity的容量(capacity )根据需要指定此ByteBuffer分配给内存)或最大可用空间。 例如我们new byte[233]; 这里233是容量。 指定模拟数组、capacity后不能更改。 如果capacity () )有参加则为setter,如果没有参加则为getter。 下面的limit与位置属性相同。 kddzp稍有不同。

limit边界(limit,请原谅我不相信钻石),初始化时等于capacity,我们申请了capacity那么大的空间,但我们并不总是有那么大的数据。 java使用limit来定义我们的数据边界在哪里。 例如,如果limit=10,capacity=20,则10到20之间为空白空间。 (但我们也不能直接使用这个空间)。 我们的所有读写操作都受limit限制,不能操作超过limit的空间。 如果想使用上面10到20之间的空间的话,使用limit等30。 然后我们可以操作最多30个空间。 limit的最大能量与capacity相同。 因为我们申请了capacity左右的空间。 如果limit超过capacity,则会进行不属于ByteBuffer的操作。 和数组越界是一样的理由。 请记住一句话。 我们的读写操作都是从position开始,终于limit,最多等于capacity。

“定位”(position )在初始化时为0,指向下一个操作位置。 与PC指针相似。 无论我们读还是写,操作的都是position指向的位置,操作结束后添加position,指向下一个操作的位置。 position的最大能量等于limit,此时无法操作。 这是因为,如果操作position后大于limit,则会越界报告Java.nio.bufferoverflowexception的异常。

的温暖大豆标记(温暖大豆)在初始化时为-1,类似书签。 在某个时刻调用kddzp ) )方法时,kddzp等于position。 然后我们想回到kddzp那里的时候,可以调用reset (方法)。 网络用语标志是kddzp音译。

ByteBuffer方法allocate () publicstaticbytebufferallocate (int capacity ) )。

分配新字节缓冲器。

the new buffer’spositionwillbezero,its limit will be its capacity,its kddzp will be undefined,andeachofitselementswillbeinitializalized

ByteBuffer初始化方法,参数为int或capacity。 例如,bytebufferbytebuffer=byte buffer.allocate (20; 为ByteBuffer打开了20字节大小的内存空间。 如果指定了capacity,则在重新new byte buffer之前无法更改。 但是,那是另一个字节缓冲器。

订单(publicfinalbytebufferorder (byteorder bo ) )。

修改缓冲区字节顺序。

参数:

bo - The new byte order,either big _ endianorlittle _ endian

ByteBuffer有字节序,字节序是将字节放入ByteBuffer的顺序。 例如,我们ByteBuffer的存储器地址是0xFFFF 0000到0xFFFF 00FF。 我们现在把byte数组放入ByteBuffer中。 那么,是从0xFFFF 00FF开始放还是从0xFFFF 0000开始放? ByteOrder表示我们是以什么顺序放置的。 byte还不知道有什么区别,但在读写多个字节的对象时

体现出不同了,比如读int类型从0xFFFF 0000到0xFFFF 0004跟从0xFFFF 0004到0xFFFF 0000完全就是两个不同的数。order()有参数就是设置字节序,没参数就是返回ByteBuffer当前字节序。不过这个感觉一般来说不用管。

put()

public abstract ByteBuffer put(byte b)
Relative put method (optional operation).
Writes the given byte into this buffer at the current position, and then increments the position.

就是把数据放进ByteBuffer的方法,有多种变种,比如put(byte),put(byte[]),put(byte[] src,int offset,int length),put(ByteBuffer src)等等。你写入多少个字节的数据position就加多少。

flip()

public final Buffer flip()
Flips this buffer. The limit is set to the current position and then the position is set to zero. If the kddzp is defined then it is discarded.

flip()方法就是把limit设置成当前position,然后position=0,附带把kddzp置-1,也就是舍弃你可能有的标记。简单来说这个方法的作用就是把写模式变成读模式。比如你初始化一个ByteBuffer,此时position=0,limit=capacity。然后你向其中写入了5个字节的数据(假设capacity大于5),此时position=5,limit=capacity。现在你想把写入的5字节数据读出来,假如你直接读,那么你会读到位与5的数据,然后position=6。这显然不符合我们的需求。我们需要把position置0,因为我们希望下个操作的数据位于0位置。这样我们能正确读出那五个数据了,但是我们没有设置limit,那么我们完全有可能读到5以后的数据。这样也是不行的,那么我们就需要把limit设置成5,也就是写完后position的位置。这样我们就只会读5个字节的数据,觉不会多读。

array()

public final byte[] array()
Returns the byte array that backs this buffer (optional operation).
Modifications to this buffer’s content will cause the returned array’s content to be modified, and vice versa.
Invoke the hasArray method before invoking this method in order to ensure that this buffer has an accessible backing array.

前面说过ByteBuffer实质就是一个byte[],这个方法就是返回ByteBuffer底层的byte数组,也就是说你对ByteBuffer的所有操作实质就是操作这个byte数组,反之亦然。需要注意的是操作数组不会影响ByteBuffer的position,limit,kddzp等属性,同时对数组的操作和一般数组没有任何区别,不受ByteBuffer那些属性影响。

get()

public abstract byte get()
Relative get method. Reads the byte at this buffer’s current position, and then increments the position.

用flip()或者手动准备好读后,可以使用get()方法读取ByteBuffer的数据,和put()方法一样get()有很多延伸,可以根据自己需要选取。

wrap()

public static ByteBuffer wrap(byte[] array)
Wraps a byte array into a buffer.
The new buffer will be backed by the given byte array; that is, modifications to the buffer will cause the array to be modified and vice versa. The new buffer’s capacity and limit will be array.length, its position will be zero, and its kddzp will be undefined. Its backing array will be the given array, and its array offset> will be zero.

文档说的很清楚了,就是以你给定的字节数组为底层数组构建一个ByteBuffer。

//wrap()创建ByteBufferbyte[] array=new byte[233];ByteBuffer byteBuffer=ByteBuffer.wrap(array);//allocate创建ByteBufferByteBuffer byteBuffer=ByteBuffer.allocate(233);byte[] array=byteBuffer.array();

上面两种创建ByteBuffer的方式,前者不会开辟新的内存空间,而是直接使用array的内存空间,同时保留array数组原有数据。而后者会开辟新的内存空间。

clear()

public final Buffer clear()
Clears this buffer. The position is set to zero, the limit is set to the capacity, and the kddzp is discarded.

clear()做的就是把position=0,limit=capacity,kddzp=-1,clear()只是移动指针,不改变ByteBuffer里面的数据。此时如果你要写,那么ByteBuffer就相当于空的,如果你要读,那么ByteBuffer就相当于写满数据的。

rewind()

public final Buffer rewind()
Rewinds this buffer. The position is set to zero and the kddzp is discarded.

如上,position=0,kddzp被舍弃,也就是说你读写到一半或读写完了,现在想从头开始,那就调用rewind()方法,从头开始。

campact()

public abstract ByteBuffer compact()
Compacts this buffer (optional operation).
The bytes between the buffer’s current position and its limit, if any, are copied to the beginning of the buffer. That is, the byte at index p = position() is copied to index zero, the byte at index p + 1 is copied to index one, and so forth until the byte at index limit() - 1 is copied to index n = limit() - 1 - p. The buffer’s position is then set to n+1 and its limit is set to its capacity. The kddzp, if defined, is discarded.
The buffer’s position is set to the number of bytes copied, rather than to zero, so that an invocation of this method can be followed immediately by an invocation of another relative put method.

如上所说,调用campact()方法会把position和limit之间的数据移动到ByteBuffer开始的地方,然后position=limit-position,也就是position接在被转移的数据后面,然后limit=capacity。这个方法的作用是把我们未读完的数据放到前面,以便我们接着后面写入数据,因为我们不能期望一次把所有数据读完。总会出现在还未读完数据的时候需要写入数据的情况,此时如果你不需要未读的那些数据,可以clear(),如果需要保留那些数据则campact()。

最后

其实写博客很难受,要考虑写得对写得全,又要通俗易懂,写到最后我都有点偷工减料了,如果有哪里不清楚,自己写段简单代码验证一下就是了,更多ByteBuffer特性用法请参阅官方API文档。同时如果有哪里写错了还请不吝赐教。最后祝各位能找到自己的真物。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。