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

我已经修改了 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

        }

    }



守着星空守着你
浏览 147回答 3
3回答

扬帆大鱼

您的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()

皈依舞

我认为你用所有这些defer东西和你的“技巧”错误检查弄乱了代码逻辑。文件在刷新或关闭时被明确写入。在打开阅读它之前,您只需复制到 new.txt 而不关闭它。推迟关闭文件在具有多个退出的函数中是整洁的:它确保一旦离开函数就关闭文件。但是您的 main 要求在复制后关闭 new.txt,然后再重新打开它。所以不要推迟这里的关闭。顺便说一句:你对 log.Fatal 终止代码而不调用你的 defer 的防御是,好吧,至少很奇怪。文件都被操作系统置于某种适当的状态,绝对没有必要像这样复杂化。

一只名叫tom的猫

我会建议使用io.MultiWriter。通过这种方式,您只能从 src 读取一次。小文件增益不大,但大文件更快。  w :=  io.MultiWriter(dest, os.Stdout)
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go