不要在可写文件上调用defer Close

当关闭一个可写文件时,该操作会又系统调用call完成,该调用可能会返回一下错误代码。

ERRORS
     The close() system call will fail if:

     [EBADF]            fildes is not a valid, active file descriptor.

     [EINTR]            Its execution was interrupted by a signal.

     [EIO]              A previously-uncommitted write(2) encountered an input/output
                        error.

当EIO 错误发生时,写入文件的操作将会丢失数据。如果还是直接 defer Close,我们将会丢失该错误消息。
因此,在defer中,我们应该再检查下Close返回的error是否为nil。

func helloNotes() (err error) {
    var f *os.File
    f, err = os.Create(/tmp/notes.txt")
    if err != nil {
        return
    }

    defer func() {
        cerr := f.Close()
        if err == nil {
            err = cerr
        }
    }()

    err = io.WriteString(f, "hello world")
    return
}
或者
func helloNotes() error {
    f, err := os.Create("/tmp/notes.txt")
    if err != nil {
        return err
    }
    defer f.Close()

    if err = io.WriteString(f, "hello world"); err != nil {
        return err
    }

    return f.Sync()
}

你可能感兴趣的:(不要在可写文件上调用defer Close)