【问题标题】:Go. Writing []byte to file results in zero byte file走。将 []byte 写入文件会产生零字节文件
【发布时间】:2017-07-11 02:52:09
【问题描述】:

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

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 表示写入字节数的变量也超过一千 - 文件根本不应该为空。该文件已创建,但它完全是空的。怎么了?

【问题讨论】:

    标签: file go io gob


    【解决方案1】:

    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
    }
    

    【讨论】:

    • 抱歉浪费您的时间:我对 Go 完全陌生,它是“基础设施”。非常感谢您的详细解释,您的回答相当完美。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-11-02
    • 1970-01-01
    • 2012-07-13
    • 2021-09-04
    • 2021-07-23
    • 2022-01-10
    相关资源
    最近更新 更多