Golang如何将切片编码为紧凑二进制数据并写入文件

Golang如何将切片编码为紧凑二进制数据并写入文件 我有一个切片 var slice []uint slice = [1,2,3,4,5,6,7,8,9,10]

我想将其编码为打包的二进制数据,尝试使用 Binary.LittleEndian.PutUint32(byte, slice) 但无效,并且我希望这是一个短整型(2字节)而不是标准的4字节无符号整数。似乎找不到实现此功能的方法。这个打包的二进制数据将被写入文件。

func main() {
    fmt.Println("hello world")
}
3 回复

谢谢

我最终的做法是(在阅读你的答案之前):

    data = make([]byte, 2)
    //from json , skipped the append to slice
    binary.LittleEndian.PutUint16(data, uint16(number.(float64)))
    _, err = f.Write(data)

更多关于Golang如何将切片编码为紧凑二进制数据并写入文件的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


package main

import (
	"encoding/binary"
	"fmt"
	"unsafe"
)

func main() {
	var slice []uint
	slice = []uint{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}

	// short uint(2 byte one)
	soUint16 := int(unsafe.Sizeof(uint16(0)))
	buf := make([]byte, soUint16*len(slice))
	for i, u := range slice {
		binary.LittleEndian.PutUint16(buf[soUint16*i:], uint16(u))
	}
	// write buf to file

	fmt.Printf("%d\n", buf)
}

https://play.golang.org/p/YH10WskUusP

你可以使用 binary.Write 配合自定义的写入逻辑来实现将 []uint 编码为紧凑的二进制数据。由于 uint 的大小在 Go 中依赖于平台(可能是 32 位或 64 位),而你需要的是 2 字节的短整型(16 位),你应该先将切片转换为 []uint16,然后将其写入文件。以下是一个示例:

package main

import (
    "encoding/binary"
    "fmt"
    "os"
)

func main() {
    // 原始切片,使用 uint 类型
    var slice []uint = []uint{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}

    // 将 slice 转换为 []uint16,因为我们需要 2 字节的短整型
    // 注意:这里假设 slice 中的值都适合 uint16(即不超过 65535)
    uint16Slice := make([]uint16, len(slice))
    for i, v := range slice {
        uint16Slice[i] = uint16(v)
    }

    // 创建或打开文件用于写入
    file, err := os.Create("output.bin")
    if err != nil {
        fmt.Println("Error creating file:", err)
        return
    }
    defer file.Close()

    // 使用 binary.Write 将 []uint16 写入文件,采用小端字节序
    // 注意:binary.Write 会为每个元素写入 2 字节
    err = binary.Write(file, binary.LittleEndian, uint16Slice)
    if err != nil {
        fmt.Println("Error writing to file:", err)
        return
    }

    fmt.Println("Slice encoded and written to output.bin")
}

在这个示例中,我们首先将 []uint 转换为 []uint16,以确保每个元素占用 2 字节。然后,使用 binary.Write 将整个切片写入文件,采用小端字节序。写入的文件 output.bin 将包含紧凑的二进制数据,每个值占用 2 字节。

如果你需要手动控制写入过程(例如,避免使用 binary.Write 的额外开销),也可以使用循环和 binary.LittleEndian.PutUint16 来逐个写入元素:

package main

import (
    "encoding/binary"
    "fmt"
    "os"
)

func main() {
    var slice []uint = []uint{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}

    file, err := os.Create("output.bin")
    if err != nil {
        fmt.Println("Error creating file:", err)
        return
    }
    defer file.Close()

    // 创建一个缓冲区来存储 2 字节的数据
    buf := make([]byte, 2)
    for _, v := range slice {
        // 将每个值转换为 uint16 并写入缓冲区
        binary.LittleEndian.PutUint16(buf, uint16(v))
        // 将缓冲区写入文件
        _, err := file.Write(buf)
        if err != nil {
            fmt.Println("Error writing to file:", err)
            return
        }
    }

    fmt.Println("Slice encoded and written to output.bin")
}

这种方法逐个处理切片元素,将每个 uint 值转换为 uint16 并使用 PutUint16 编码为 2 字节,然后写入文件。这提供了更细粒度的控制,但代码稍长。两种方法都能生成紧凑的二进制文件。

回到顶部