Go.将[]byte写入文件会导致生成零字节的文件。

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 超过一千 - 文件也不应该为空。文件已创建,但是它是完全空的。出了什么问题吗?

1个回答

4

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

还要注意,您可以直接写入os.File,而不需要创建一个“围绕”它的缓冲写入器。(*os.File实现了io.Writer)。

此外,请注意,您可以将gob.Encoder直接指向os.File,因此甚至不需要使用bytes.Buffer

另外,os.MkdirAll()可能会失败,请检查其返回值。

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

最后,最好使用一个error返回值来标识Serialize()的失败,以便调用方有机会检查操作是否成功,并相应地采取行动。

因此,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
}

很抱歉浪费您的时间:我对Go语言和它的“基础设施”完全是新手。非常感谢您详细的解释,您的回答相当完美。 - Павел Вайсберг

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接