Golang中的二进制编码/解码文件给出不同的校验和

kr98yfug  于 2022-12-07  发布在  Go
关注(0)|答案(1)|浏览(151)

我正在用golang对文件进行编码和解码。我特别需要我正在使用的2D数组,这只是测试代码来说明这一点。我不完全确定我做错了什么,我尝试将文件转换为uint 32数字列表,然后获取这些数字并将其转换回文件。问题是,当我这样做时,文件看起来很好,但校验和不“我怀疑我在转换到uint 32的过程中做错了什么。我不得不使用switch/case,因为我无法确定在给定文件的末尾将读取多少字节。

package main

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

const (
    headerSeq = 8
    body      = 24
)

type part struct {
    Seq  int
    Data uint32
}

func main() {
    f, err := os.Open("speech.pdf")
    if err != nil {
        panic(err)
    }
    defer f.Close()

    reader := bufio.NewReader(f)
    b := make([]byte, 4)
    o := make([][]byte, 0)
    var value uint32
    for {
        n, err := reader.Read(b)
        if err != nil {
            if err != io.EOF {
                panic(err)
            }
        }

        if n == 0 {
            break
        }
        fmt.Printf("len array %d\n", len(b))
        fmt.Printf("len n %d\n", n)
        switch n {
        case 1:
            value = uint32(b[0])
        case 2:
            value = uint32(uint32(b[1]) | uint32(b[0])<<8)
        case 3:
            value = uint32(uint32(b[2]) | uint32(b[1])<<8 | uint32(b[0])<<16)
        case 4:
            value = uint32(uint32(b[3]) | uint32(b[2])<<8 | uint32(b[1])<<16 | uint32(b[0])<<24)
        }
        fmt.Println(value)
        bs := make([]byte, 4)
        binary.BigEndian.PutUint32(bs, value)
        o = append(o, bs)
    }
    fo, err := os.OpenFile("test.pdf", os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600)
    if err != nil {
        panic(err)
    }
    defer fo.Close()

    for _, ba := range o {
        _, err := fo.Write(ba)
        if err != nil {
            panic(err)
        }
    }
}
zqdjd7g9

zqdjd7g91#

因此,您希望在文件中写入和读取不同长度的数组。

import "encoding/binary"

// You need a consistent byte order for reading and writing multi-byte data types
const order = binary.LittleEndian

var dataToWrite = []byte{ ... ... ... }
var err error

// To write a recoverable array of varying length
var w io.Writer
// First, encode the length of data that will be written
err = binary.Write(w, order, int64(len(dataToWrite)))
// Check error
err = binary.Write(w, order, dataToWrite)
// Check error

// To read a variable length array
var r io.Reader
var dataLen int64
// First, we need to know the length of data to be read
err = binary.Read(r, order, &dataLen)
// Check error
// Allocate a slice to hold the expected amount of data
dataReadIn := make([]byte, dataLen)
err = binary.Read(r, order, dataReadIn)
// Check error

这种模式不仅适用于byte,也适用于任何其他固定大小的数据类型。有关编码的详细信息,请参阅binary.Write
如果编码数据的大小非常重要,可以通过将数组长度存储为带有binary.PutVarintbinary.ReadVarintvarint来保存一些字节

相关问题