为了账号安全,请及时绑定邮箱和手机立即绑定

golang zlib 读取器输出未复制到标准输出

golang zlib 读取器输出未复制到标准输出

Go
守着星空守着你 2021-11-29 17:00:36
我已经修改了 zlib 包的官方文档示例,以使用打开的文件而不是一组硬编码字节(下面的代码)。该代码读取源文本文件的内容并使用 zlib 包对其进行压缩。然后我尝试读回压缩文件并将其解压缩的内容打印到标准输出中。代码没有错误,但它也没有做我期望它做的事情;即把解压后的文件内容显示到标准输出中。另外:是否有另一种方式来显示此信息,而不是使用io.Copy?    package main    import (        "compress/zlib"        "io"        "log"        "os"    )    func main() {        var err error        // This defends against an error preventing `defer` from being called        // As log.Fatal otherwise calls `os.Exit`        defer func() {            if err != nil {                log.Fatalln("\nDeferred log: \n", err)            }        }()        src, err := os.Open("source.txt")        if err != nil {            return        }        defer src.Close()        dest, err := os.Create("new.txt")        if err != nil {            return        }        defer dest.Close()        zdest := zlib.NewWriter(dest)        defer zdest.Close()        if _, err := io.Copy(zdest, src); err != nil {            return        }        n, err := os.Open("new.txt")        if err != nil {            return        }        r, err := zlib.NewReader(n)        if err != nil {            return        }        defer r.Close()        io.Copy(os.Stdout, r)        err = os.Remove("new.txt")        if err != nil {            return        }    }
查看完整描述

3 回答

?
扬帆大鱼

TA贡献1799条经验 获得超9个赞

您的deferfunc 不做任何事情,因为您err在每次新赋值时都隐藏变量。如果想要 adefer运行,从一个单独的函数返回,并log.Fatal在 return 语句之后调用。


至于为什么看不到任何输出,那是因为您推迟了所有 Close 调用。在zlib.Writer不刷新,直到函数退出之后,也不是目标文件。Close()在需要的地方明确调用。


zdest := zlib.NewWriter(dest)


if _, err := io.Copy(zdest, src); err != nil {

    log.Fatal(err)

}

zdest.Close()

dest.Close()


查看完整回答
反对 回复 2021-11-29
?
皈依舞

TA贡献1851条经验 获得超3个赞

我认为你用所有这些defer东西和你的“技巧”错误检查弄乱了代码逻辑。

文件在刷新或关闭时被明确写入。打开阅读它之前,您只需复制到 new.txt 而不关闭它。

推迟关闭文件在具有多个退出的函数中是整洁的:它确保一旦离开函数就关闭文件。但是您的 main 要求在复制后关闭 new.txt,然后再重新打开它。所以不要推迟这里的关闭。

顺便说一句:你对 log.Fatal 终止代码而不调用你的 defer 的防御是,好吧,至少很奇怪。文件都被操作系统置于某种适当的状态,绝对没有必要像这样复杂化。


查看完整回答
反对 回复 2021-11-29
?
一只名叫tom的猫

TA贡献1906条经验 获得超3个赞

我会建议使用io.MultiWriter。通过这种方式,您只能从 src 读取一次。小文件增益不大,但大文件更快。

  w :=  io.MultiWriter(dest, os.Stdout)


查看完整回答
反对 回复 2021-11-29
  • 3 回答
  • 0 关注
  • 146 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信