3

我尝试将结构化数据序列化到文件中。我查看了一些示例并进行了这样的构造:

func (order Order) Serialize(folder string) {
    b := bytes.Buffer{}
    e := gob.NewEncoder(&b)
    err := e.Encode(order)
    if err != nil { panic(err) }

    os.MkdirAll(folder, 0777)
    file, err := os.Create(folder + order.Id)
    if err != nil {  panic(err) }
    defer file.Close()


    writer := bufio.NewWriter(file)
    n, err := writer.Write(b.Bytes())

    fmt.Println(n)

    if err != nil {
        panic(err)
    }
}

Serialize是一种将其对象序列化为由其id属性调用的文件的方法。我查看了调试器 - 字节缓冲区在写入之前包含数据。我的意思是对象已完全初始化。甚至n表示写入字节数量的变量也超过一千 - 文件根本不应该是空的。该文件已创建,但它完全是空的。怎么了?

4

1 回答 1

4

bufio.Writer(正如包名所暗示的)使用缓冲区来缓存写入。如果您曾经使用过它,则必须Writer.Flush()在完成写入后调用以确保将缓冲数据写入底层io.Writer.

另请注意,您可以直接写入os.File,而无需“围绕”它创建缓冲写入器。(*os.File实现io.Writer)。

另请注意,您可以创建gob.Encoder直接定向到 的os.File,因此即使是bytes.Buffer也是不必要的。

os.MkdirAll()可能失败,检查它的返回值。

此外,最好使用文件路径的“连接”部分来filepath.Join()处理文件夹名称末尾的额外/缺失斜杠。

最后,最好Serialize()用一个error返回值来表示 的失败,这样调用方就有机会检查操作是否成功,并采取相应的行动。

所以Order.Serialize()应该是这样的:

func (order Order) Serialize(folder string) error {
    if err := os.MkdirAll(folder, 0777); err != nil {
        return err
    }

    file, err := os.Create(filepath.Join(folder, order.Id))
    if err != nil {
        return err
    }
    defer file.Close()

    if err := gob.NewEncoder(file).Encode(order); err != nil {
        return err
    }

    return nil
}
于 2017-02-21T13:09:08.647 回答