走。将[]字节写入文件会产生零字节文件

时间:2017-02-21 13:01:24

标签: file go io gob

我尝试将结构化数据序列化为文件。我查看了一些例子并制作了这样的结构:

deparse()

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

1 个答案:

答案 0 :(得分:4)

bufio.Writer(作为包名称提示)使用缓冲区来缓存写入。如果你曾经使用它,你必须在写完它时调用Writer.Flush()以确保缓冲的数据被写入底层的io.Writer

另请注意,您可以直接写入os.File,无需创建缓冲编写器"周围"它。 (*os.File实施io.Writer)。

另请注意,您可以创建直接定向到os.File的{​​{3}},因此即使是gob.Encoder也是如此。

同样bytes.Buffer可能会失败,请检查其返回值。

此外,它更好地连接"使用os.MkdirAll()的文件路径的一部分,它处理文件夹名称末尾的额外/缺失斜杠。

最后,最好发出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
}