首页 » SEO优化 » php数组转byte技巧_ByteArray转byte的两种办法

php数组转byte技巧_ByteArray转byte的两种办法

访客 2024-11-07 0

扫一扫用手机浏览

文章目录 [+]

public ByteBuffer get(byte[] dst, int offset, int length) { checkBounds(offset, length, dst.length); if (length > remaining()) throw new BufferUnderflowException(); int end = offset + length; for (int i = offset; i < end; i++) dst[i] = get(); return this;}public ByteBuffer get(byte[] dst) { return get(dst, 0, dst.length);}

这两个get函数,都是先创建byte[]数组并传入,然后将数据写入。
把稳这里就须要知道创建的byte[]数组的长度,一样平常利用

int len = byteBuffer.limit() - byteBuffer.position();

这里就涉及到ByteArray的几个属性

php数组转byte技巧_ByteArray转byte的两种办法

capacity:容量,不能改变,超过容量会报错limit:第一个不可读写的位置,即末了一个数据位置的后一位。
实际上便是数据长度,它不能超过容量。
position:当前的位置。

那么它们三个是如何变革的?看下面的图片

php数组转byte技巧_ByteArray转byte的两种办法
(图片来自网络侵删)

可以看到当我们写入数据的时候,position会移动。
当我们写完数据准备读数据时,须要先调用flip将position移至开头,这样才能读出完全的数据。

但是我们也可以从中间开始读数据,以是我们要读出的数据长度是limit-position,而不仅仅是limit

利用array函数获取

但是ByteArray还有其余一个函数,之前很少把稳到,那就array

public final byte[] array() { if (hb == null) throw new UnsupportedOperationException(); if (isReadOnly) throw new ReadOnlyBufferException(); return hb;}

这个直接得到一个byte[],那么直策应用这个不是更好么?

我们可以看到这个byte数组是ByteArray的一个属性hb,且这个hb有为null的时候。

那么这个hb是什么?我们看看源码

final byte[] hb; // Non-null only for heap buffers

可以看到只有在heap buffer中才不为空,那么什么是heap buffer?

这里就涉及到ByteArray的实现,通过代码可以看到ByteArray是一个抽象类,我们实际利用的都是它的实现类HeapByteBuffer和DirectByteBuffer。

HeapByteBuffer和DirectByteBuffer

我们创建ByteArray的时候会利用allocate函数,在ByteArray里有两个函数

public static ByteBuffer allocateDirect(int capacity) { // Android-changed: Android's DirectByteBuffers carry a MemoryRef. // return new DirectByteBuffer(capacity); DirectByteBuffer.MemoryRef memoryRef = new DirectByteBuffer.MemoryRef(capacity); return new DirectByteBuffer(capacity, memoryRef);}public static ByteBuffer allocate(int capacity) { if (capacity < 0) throw new IllegalArgumentException(); return new HeapByteBuffer(capacity, capacity);}

可以看到这两个函数便是分别创建HeapByteBuffer和DirectByteBuffer

那么它们两个有什么差异?

DirectByteBuffer不是分配在堆上的,它不被GC直接管理(但Direct Buffer的JAVA工具是归GC管理的,只要GC回收了它的JAVA工具,操作系统才会开释Direct Buffer所申请的空间),它彷佛给人觉得是“内核缓冲区(buffer in kernel)”。
HeapByteBuffer则是分配在堆上的,或者我们可以大略理解为Heap Buffer便是byte[]数组的一种封装形式,查看JAVA源代码实现,HeapByteBuffer也的确是这样。
说白了便是HeapByteBuffer是在JVM堆内存等分配会被JVM管理回收,但是DirectByteBuffer是直接由系统内存进行分配,不被JVM管理。
通过上面的差异看到:

1、创建和开释DirectByteBuffer的代价比HeapByteBuffer得要高,由于JVM堆等分配和开释内存肯定比系统分配和创建内存高效

2、由于平时的read/write,都会在I/O设备与运用程序空间之间经历一个“内核缓冲区”。
DirectByteBuffer就好比是“内核缓冲区”上的缓存,不直接管GC管理;而Heap Buffer就仅仅是byte[]字节数组的包装形式。
因此把一个Direct Buffer写入一个Channel的速率要比把一个HeapByteBuffer写入一个Channel的速率要快。

以是这两个类操作起来各有好处,要视情形而定,一样平常如果是一个ByteBuffer常常被重用的话,就可以利用DirectByteBuffer工具。
如果是须要常常开释和分配的地方用HeapByteBuffer工具。

从它们处理get或put数据上就可以看到差别。
这里以get为例:

//HeapByteBufferpublic byte get() { return hb[ix(nextGetIndex())];}

HeapByteBuffer的get很大略,便是直接从hb中获取相应位置的数据

//DirectByteBufferpublic final byte get() { if (!memoryRef.isAccessible) { throw new IllegalStateException("buffer is inaccessible"); } return get(ix(nextGetIndex()));}private byte get(long a) { return Memory.peekByte(a);}

DirectByteBuffer的get函数终极是利用Memory的peekByte来获取的。
以是DirectByteBuffer的操作都是通过Memory进行处理的。

结论

以是我们知道HeapByteBuffer是分配在堆上的,实质上便是byte[],以是它的hb不为null,便是这个byte[]。
以是HeapByteBuffer可以直策应用array函数得到byte[] 但是DirectByteBuffer就弗成,由于它的hb是null的。
以是DirectByteBuffer只能利用get函数获取byte[]

这里把稳,在高版本(至少android 29,详细从哪个版本不清楚)上DirectByteBuffer的hb已经不是null了,且也有数据,但是这个数据是否是正常的数据还未进行调研,为了保险起见还是利用get函数安全一些

作者:BennuCTech链接:https://juejin.cn/post/7074418793782444039

相关文章

php断定几种来路技巧_实例讲解防盗链技能

盗链的定义此内容不在自己做事器上,而通过技能手段,绕过别人放广告有利益的终极页,直接在自己的有广告有利益的页面上向终极用户供应此内...

SEO优化 2024-12-19 阅读0 评论0

php毛病级别设置技巧_php设置缺点级别

php缺点级别设置在php.ini中可以设置做事器对缺点的报警级别。在默认情形下,php将报告除了关照之外的所有缺点。缺点报告级别...

SEO优化 2024-12-19 阅读0 评论0