gpt4 book ai didi

go - 在 go 中按顺序将 protobuf 消息写入文件

转载 作者:行者123 更新时间:2023-12-01 21:11:58 29 4
gpt4 key购买 nike

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

最佳答案

If you want to write multiple messages to a single file or stream, it is up to you to keep track of where one message ends and the next begins. The Protocol Buffer wire format is not self-delimiting, so protocol buffer parsers cannot determine where a message ends on their own. The easiest way to solve this problem is to write the size of each message before you write the message itself. When you read the messages back in, you read the size, then read the bytes into a separate buffer, then parse from that buffer.



Source

1. 编写 Protobuf

将您的 protobuf 编码为 []byte并调用 Write连同您要写入的文件为 io.Writer .这将写入 msg 的长度到 io.Writer写之前 msg本身。
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
}
*os.File输入 Go 满足 io.Readerio.Writer接口(interface),所以你不应该遇到任何问题。

感谢@Brits 指出这一点。

祝你好运!

关于go - 在 go 中按顺序将 protobuf 消息写入文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59163455/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com