2017-02-21 156 views
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

bufio.Writer(作为软件包名称提示)使用缓冲区来缓存写入。如果您曾经使用它,则必须在完成写入操作后调用Writer.Flush(),以确保将缓冲数据写入底层io.Writer

另外请注意,您可以直接写入os.File,不需要创建一个缓冲作家“围绕”它。 (*os.File执行io.Writer)。

另请注意,您可以创建直接转向os.Filegob.Encoder,因此即使是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 
} 
+0

对不起,浪费你的时间:我完全新的去和它的“基础设施”。非常感谢您的详细解释,您的答案相当完美。 –