arrays - 访问混合8/16/32位字的好方法

标签 arrays io stream kotlin

我的内存中有大量的二进制数据,我需要从随机访问的字节对齐地址进行读取/写入。但是,有时我需要读/写8位单词,有时(大端)16位单词,有时(大端)32位单词。

有一个简单的解决方案,将数据表示为ByteArray并手动实现16/32位读/写:

class Blob (val image: ByteArray, var ptr: Int = 0) {
  fun readWord8(): Byte = image[ptr++]

  fun readWord16(): Short {
    val hi = readWord8().toInt() and 0xff
    val lo = readWord8().toInt() and 0xff
    return ((hi shl 8) or lo).toShort()
  }

  fun readWord32(): Int {
    val hi = readWord16().toLong() and 0xffff
    val lo = readWord16().toLong() and 0xffff
    return ((hi shl 16) or lo).toInt()
  }
}

(对于writeWord8 / writeWord16 / writeWord32同样)。

有一个更好的方法吗?当Java本身已经在内部使用big-endian表示形式时,执行所有这些字节转换操作似乎效率很低...

要重申,我需要读写访问随机寻找 8/16/32位访问到big-endian单词。

最佳答案

您可以使用Java NIO ByteBuffer :

val array = ByteArray(100)
val buffer = ByteBuffer.wrap(array)

val b = buffer.get()
val s = buffer.getShort()
val i = buffer.getInt()

buffer.put(0.toByte())
buffer.putShort(0.toShort())
buffer.putInt(0)

buffer.position(10)

新创建的ByteBuffer的字节顺序为BIG_ENDIAN,但仍可以使用 order(ByteOrder) 函数更改。

另外,如果要避免显式创建ByteBuffer.allocate(size),请使用 buffer.array() ByteArray

有关ByteBuffer用法的更多信息:see this question

关于arrays - 访问混合8/16/32位字的好方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40610682/

相关文章:

javascript - 在 JavaScript 中生成所有可能的可变长度逗号分隔字符串组合

c# - 在 C# 中使用 (IDisposable obj = new ...) 在流中写入代码块(例如 XML)

php - VB 类流的 PHP 等价物是什么?

arrays - 为什么这些分配数组/列表的不同方法会产生不同的值?

python - 如何将圆盘形掩码应用于 NumPy 数组?

arrays - JQ 检查作为参数给出的数组中的值

java - 使用随机访问文件的 Guava multimap?

java - 输入流未被读取

io - 如何自动刷新Perl 6文件?

java - Servlet 处理 applet 通信和 http 请求