如何在Kotlin中将Int转换为ByteArray,然后再将其转回Int?

9

以下是我的代码:

整型 -> 字节数组

private fun write4BytesToBuffer(buffer: ByteArray, offset: Int, data: Int) {
    buffer[offset + 0] = (data shr 24).toByte()
    buffer[offset + 1] = (data shr 16).toByte()
    buffer[offset + 2] = (data shr 8).toByte()
    buffer[offset + 3] = (data shr 0).toByte()
}

字节数组 -> 整数

private fun read4BytesFromBuffer(buffer: ByteArray, offset: Int): Int {
    return (buffer[offset + 0].toInt() shl 24) or
           (buffer[offset + 1].toInt() shl 16) or
           (buffer[offset + 2].toInt() shl 8) or
           (buffer[offset + 3].toInt() and 0xff)
}

对于-32,768到32,767之间的任何值,它都可以无问题地工作。 然而,它不能处理更大的值。例如:

val buffer = ByteArray(10)
write4BytesToBuffer(buffer, 0, 324)
read4BytesFromBuffer(buffer, 0) // It returns 324 ***OK***

val buffer = ByteArray(10)
write4BytesToBuffer(buffer, 0, 40171)
read4BytesFromBuffer(buffer, 0) // It returns -25365 ***ERROR***

你看到我哪里错了吗?


1
你可以按照这里的描述使用Java的ByteBuffer:https://dev59.com/sm855IYBdhLWcg3wMBPV - David Soroko
4个回答

14

以下是解决方案。

Int -> ByteArray

private fun write4BytesToBuffer(buffer: ByteArray, offset: Int, data: Int) {
    buffer[offset + 0] = (data shr 0).toByte()
    buffer[offset + 1] = (data shr 8).toByte()
    buffer[offset + 2] = (data shr 16).toByte()
    buffer[offset + 3] = (data shr 24).toByte()
}

或者说更简洁地说

for (i in 0..3) buffer[offset + i] = (data shr (i*8)).toByte()

字节数组 -> 整数

private fun read4BytesFromBuffer(buffer: ByteArray, offset: Int): Int {
    return (buffer[offset + 3].toInt() shl 24) or
           (buffer[offset + 2].toInt() and 0xff shl 16) or
           (buffer[offset + 1].toInt() and 0xff shl 8) or
           (buffer[offset + 0].toInt() and 0xff)
}

我不确定这是否正确,因为我还没有尝试过,但是在尝试之前我会点赞,因为你是第一个尝试这个的人,我已经寻找答案整整一天了 :0 - Mohammad Elsayed
@MohammadElsayed 没错。我已经进行了各种测试 :) 但如果有问题,请告诉我。 - Greelings
2
我写了 for (i in 0..3) buffer[offset + i] = (data shr (i*8)).toByte() - Guss

8

我会使用 java.nio.ByteBuffer -

fun intToBytes(i: Int): ByteArray =
    ByteBuffer.allocate(Int.SIZE_BYTES).putInt(i).array()

fun bytesToInt(bytes: ByteArray): Int =
    ByteBuffer.wrap(bytes).int

7

这里有一行代码可以让您获得一个ByteArray:

fun numberToByteArray (data: Number, size: Int = 4) : ByteArray = 
    ByteArray (size) {i -> (data.toLong() shr (i*8)).toByte()}

可以选择设置字节数(大小),你可以转换 Shorts,Ints,Longs。

只需要这样调用:

var yourByteArray = numberToByteArray (yourNumberHere)

"item.toLong()" 应该改为 "data.toLong()" 吗? - Awesomeness
该死,Kotlin没有像C#的BitConverter一样内置将类型转换为字节的类,这已经存在了20多年,我必须为每种类型创建这些方法? 这太出乎意料了... 我以为这是一种非常基本的需求。 - Damn Vegetables

0
你可以为此编写一个扩展函数
fun ByteArray.getIntAt(i: Int): Int {
    return (this[i].toInt() and 0xFF) or
            ((this[i + 1].toInt() and 0xFF) shl 8) or
            ((this[i + 2].toInt() and 0xFF) shl 16) or
            ((this[i + 3].toInt() and 0xFF) shl 24)
}

现在你可以使用它了。
val myInt = myByteArr.getIntAt(myIndex)

互相转换:
private fun Int.toByteArray(): ByteArray {
    return byteArrayOf(
        (this and 0xFF).toByte(),
        ((this shr 8) and 0xFF).toByte(),
        ((this shr 16) and 0xFF).toByte(),
        ((this shr 24) and 0xFF).toByte()
    )
}

使用它:
val myByteArray = myInt.toByteArray()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接