2017-02-21 205 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

對不起,浪費你的時間:我完全新的去和它的「基礎設施」。非常感謝您的詳細解釋,您的答案相當完美。 –