Java中iOS NSData字节操作方法的等价实现方案咨询
NSData 迁移到 Java ByteBuffer 的对应实现
你查到的Swift侧NSData对应Java侧ByteBuffer的结论是准确的,两个需求用JDK原生API就能实现,不需要引入额外依赖,注意对齐两边的内存语义、读写行为差异即可。
第一个需求:从指定缓冲区复制给定长度字节完成对象初始化
对应iOS代码:let data = NSData(bytes: array, length: 4)注意
NSData这个初始化方法会拷贝源缓冲区的指定长度字节,生成独立的内存块,和源缓冲区不共享内存。Java侧不要直接用ByteBuffer.wrap()——这个方法是直接引用源数组,修改源数组会同步影响生成的缓冲区内容,和原逻辑不符。正确实现:int copyLen = 4; // 源array为byte[]类型时 ByteBuffer data = ByteBuffer.allocate(copyLen); data.put(array, 0, copyLen); data.flip(); // 切换到读模式,对齐NSData初始化后可直接读取的语义如果源本身是已经存在的ByteBuffer实例,需要从其当前读写位置复制指定长度,要注意还原源缓冲区的读写状态:
ByteBuffer srcBuf = /* 源缓冲区实例 */; int copyLen =4; int originPos = srcBuf.position(); srcBuf.limit(originPos + copyLen); ByteBuffer data = ByteBuffer.allocate(copyLen); data.put(srcBuf); // 还原源缓冲区的position、limit,避免影响后续操作 srcBuf.position(originPos); srcBuf.limit(srcBuf.capacity()); data.flip();第二个需求:从数据对象起始位置复制指定长度字节到目标缓冲区
对应iOS代码:data.getBytes(&value, length: 4)注意这个iOS方法默认是从
data的0偏移位置开始读字节,不会修改数据对象本身的状态,且拷贝长度为传入的length值。Java侧实现时要注意临时切换读写位置,拷贝完成后还原,避免破坏原ByteBuffer的position状态:byte[] value = new byte[4]; // 目标缓冲区,长度需不小于拷贝长度 int copyLen =4; int originPos = data.position(); try { data.position(0); data.get(value, 0, copyLen); } finally { // 无论拷贝是否成功,都还原原读写位置,对齐NSData的无状态行为 data.position(originPos); }
迁移注意:
ByteBuffer自带position/limit读写游标,而NSData没有内部游标的概念,所有默认读写都从0偏移开始,这是两边最容易出隐蔽bug的差异点。如果不需要用到ByteBuffer的堆外内存、字节序转换等特性,直接用byte[]做存储载体实现逻辑会更简单,对齐NSData的语义也更直接。
内容的提问来源于stack exchange,提问作者Anush Hakobyan
相关产品推荐
相关产品推荐

