登录
首页 >  Golang >  Go问答

按顺序将 Protobuf 消息写入文件的 Golang 实现

来源:stackoverflow

时间:2024-03-27 09:06:40 482浏览 收藏

使用 Protobuf 序列化并写入文件时,您可以将 Protobuf 消息打包为字节数组,然后将其写入文件。为了按顺序读取它们,需要在写入每个消息之前先写入其长度,以便在读取时可以确定其大小。该方法使用较少的内存分配,并且可以轻松地写入或读取文件。

问题内容

我有大量类似的对象(大约数百GB),我需要将其序列化并按顺序写入文件,然后以相同的顺序读取它。如何在golang的protobuf(gogo proto)中做到这一点? Gob 有一个可以写入 io.Writer 的编码器,但 protobuf 没有类似的东西。也许 protobuf 不是达到此目的的最佳选择?我需要良好的性能和低内存分配。


解决方案


Source

1。编写 protobuf

将您的 protobuf 编组到 []byte 中,并调用 write 以及您想要作为 io.writer 写入的文件。这会在写入 msg 本身之前将 msg 的长度写入 io.writer

func write(w io.writer, msg []byte) error {
    buf := make([]byte, 4)
    binary.littleendian.putint32(buf, uint32(len(msg)))

    if _, err := w.write(buf); err != nil {
        return err
    }

    if _, err := w.write(msg); err != nil {
        return err
    }
}

2。读取 protobuf

当你想读出另一端的protobufs时,打开文件并将其作为io.reader传入。这会从文件中提取大小,然后将字节数读入 msg 缓冲区并返回。

func Read(r io.Reader) ([]byte, error) {
    buf := make([]byte, 4)
    if _, err := io.ReadFull(r, buf); err != nil {
        return nil, err
    }

    size := binary.LittleEndian.Uint32(buf)

    msg := make([]byte, size)
    if _, err := io.ReadFull(r, msg); err != nil {
        return nil, err
    }

    return msg, err
}

go 中的 *os.file 类型同时满足 io.readerio.writer 接口,因此您不会遇到任何问题。

感谢 @brits 指出了这一点。

祝你好运!

以上就是《按顺序将 Protobuf 消息写入文件的 Golang 实现》的详细内容,更多关于的资料请关注golang学习网公众号!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>