登录
首页 >  Golang >  Go问答

gzip.Close() 延迟执行以避免写入页脚

来源:stackoverflow

时间:2024-02-18 23:36:24 435浏览 收藏

Golang小白一枚,正在不断学习积累知识,现将学习到的知识记录一下,也是将我的所得分享给大家!而今天这篇文章《gzip.Close() 延迟执行以避免写入页脚》带大家来了解一下##content_title##,希望对大家的知识积累有所帮助,从而弥补自己的不足,助力实战开发!


问题内容

我正在尝试使用 gzip.newwriter 流式传输数据并将压缩数据写入 csv 文件。一切正常,除了当我使用 defer gzip.close() 时,页脚似乎没有被写入。当我尝试使用 7-zip 打开文件时,收到 unexpected end of data 消息。

注意:我已经看到这个问题(和答案),但我觉得我的问题有点不同,因为我正在写入文件而不返回字节。

据我了解,该问题中的op返回的是写入页脚之前的字节。但因为我只是写入文件,所以我不应该遇到同样的问题。

这是我的代码片段。为了简洁起见,我删除了所有错误检查。

// worker that reads invoices and compresses them into a single file.
func compressworker(c config, archived <-chan invoice, done chan<- int) {
    now := time.now().format("2006-01")
    path := filepath.join(c.outdir, now+".csv.gz")

    readcolumns := false

    f, _ := os.create(path)
    defer closewriter("csv file", f)

    cw := gzip.newwriter(f)
    cw.name = now + ".csv"

    // * this is where i originally had my defer close call.
    // defer closewriter("compression stream", cw)

    for i := range archived {
        if !readcolumns {
            b := []byte(i.csvcolumns() + ",datelastsaved\n")
            cw.write(b)
            readcolumns = true
        }

        b := []byte(i.tocsvstring() + "," + time.now().format("2006-01-02") + "\n")
        cw.write(b)
    }

    // ordinarily i'd say we defer this earlier, but that doesn't work for some
    // reason.
    closewriter("compression writer", cw)

    done <- 1
}

// print an error with a prefix string and exit.
func handleerrorwithprefix(e error, p string) {
    if e != nil {
        log.fatalf("error: %v; %v\n", p, e)
    }
}

func closewriter(n string, wc io.writecloser) {
    log.printf("closing %v\n", n)
    err := wc.close()
    handleerrorwithprefix(err, fmt.sprintf("error closing writer '%v'", n))
}

有趣的是,我从 closewriter 那里得到了这个,其中包含我的原始代码和延迟关闭:

2021/10/13 09:05:42 closing compression writer
2021/10/13 09:05:42 closing csv file

但是,当我关闭 cw 而不延迟时,我得到了这个:

2021/10/13 09:06:01 closing compression stream

我在 closewriter 中没有收到任何错误,所以我不确定为什么文件不会关闭。延迟工作是后进先出对吗?


正确答案


看来我的问题并没有太大不同:我的程序在我的作家有足够的时间完全结束之前就结束了。

在每个人评论的帮助下,我解决了这个问题,将我的 done 发送移动到工作函数开头的延迟关闭。

func compressWorker(c Config, archived <-chan Invoice, done chan<- int) {
    // Defer here ensures it will always be run last.
    defer func() {
        done <- 1
    }()

    // ...

    defer f.Close()
    defer cw.Close()

    // ...
}

理论要掌握,实操不能落!以上关于《gzip.Close() 延迟执行以避免写入页脚》的详细介绍,大家都掌握了吧!如果想要继续提升自己的能力,那么就来关注golang学习网公众号吧!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>