簡體   English   中英

在 GoLang 中將 int64 切片轉換為字節數組,反之亦然

[英]Convert Slice of int64 to byte array and vice versa in GoLang

我需要將一段 int64 轉換為 golang 中的字節數組。 我能夠成功地為單個 int64 做到這一點

var p int64 = -3984171602573983744
fmt.Println(p)
cn := make([]byte, 8)
binary.LittleEndian.PutUint64(cn, uint64(p))
fmt.Println(cn)

我如何為一片 int64 實現它?

更准確地說,我試圖調用庫中寫入數據庫的函數,該函數將字節數組作為參數。 我有一片 int64,我需要將其轉換為字節數組,反之亦然。 這可能嗎?

例如,

package main

import (
    "bytes"
    "encoding/binary"
    "fmt"
    "math"
)

func main() {

    w64 := []int64{math.MinInt64, -1, 0, 1, math.MaxInt64}
    fmt.Println(w64)

    // Write []int64 to database []byte
    wbuf := new(bytes.Buffer)
    err := binary.Write(wbuf, binary.LittleEndian, w64)
    if err != nil {
        fmt.Println("binary.Write failed:", err)
    }
    db := wbuf.Bytes()
    fmt.Printf("% x\n", db)

    // Read database []byte to []int64
    rbuf := bytes.NewBuffer(db)
    r64 := make([]int64, (len(db)+7)/8)
    err = binary.Read(rbuf, binary.LittleEndian, &r64)
    if err != nil {
        fmt.Println("binary.Read failed:", err)
    }
    fmt.Println(r64)
}

游樂場: https : //play.golang.org/p/4OscSOGZE52

輸出:

[-9223372036854775808 -1 0 1 9223372036854775807]
00 00 00 00 00 00 00 80 ff ff ff ff ff ff ff ff 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 ff ff ff ff ff ff ff 7f
[-9223372036854775808 -1 0 1 9223372036854775807]

對於 int64 的每個循環並將其存儲為binary.LittleEndian.PutUint64(cn[x:], yourUint64) ,其中x變為 0,8,16...當您循環時。 您的cn應該足夠大以獲取所有數據(它將是 8 的倍數)。 當您想閱讀時,請執行相反的操作: x1 := binary.LittleEndian.Uint64(cn[n:n+8]) ,其中n變為 0, 1, 2..

請參閱https://play.golang.org/p/YVQOAG8-Xlm以獲取更簡單的多路分離示例。

如果您的機器也是小端(很常見),您可以使用不安全的轉換來非常快速地執行此操作(不需要 for 循環)。 下面是兩個示例函數,它們處理最多 2^32 字節長的數組。 您可以更改代碼以處理更大的容量。

當然,這使用了unsafe包,因此您可能希望修改它以返回副本而不是直接使用內存。 如果您不熟悉不安全指針,可以在此處學習。

func bytesToInt64s(buf []byte) []int64 {
    if len(buf) < 1 << 16 {
        return (*[1 << 13]int64)(unsafe.Pointer(&buf[0]))[0 : len(buf)/8 : len(buf)/8]
    }
    l := len(buf)
    if l > 1 << 32 { // only use the first 2^32 bytes
       l = (1 << 32) - 1
    }
    return (*[1 << 29]int64)(unsafe.Pointer(&buf[0]))[0 : l / 8 : l / 8 ]
}

func int64sToBytes(buf []int64) []byte {
    if len(buf) < 1 << 13 {
        return (*[1 << 16]byte)(unsafe.Pointer(&buf[0]))[0 : len(buf)*8 : len(buf)*8]
    }
    l := len(buf) * 8
    if l > 1 << 32 { // only use the first 2^32 bytes
       l = (1 << 32) - 1
    }
    return (*[1 << 32]byte)(unsafe.Pointer(&buf[0]))[0 : l : l]
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM