我已经修改了 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()
皈依舞
TA贡献1851条经验 获得超3个赞
我认为你用所有这些defer
东西和你的“技巧”错误检查弄乱了代码逻辑。
文件在刷新或关闭时被明确写入。在打开阅读它之前,您只需复制到 new.txt 而不关闭它。
推迟关闭文件在具有多个退出的函数中是整洁的:它确保一旦离开函数就关闭文件。但是您的 main 要求在复制后关闭 new.txt,然后再重新打开它。所以不要推迟这里的关闭。
顺便说一句:你对 log.Fatal 终止代码而不调用你的 defer 的防御是,好吧,至少很奇怪。文件都被操作系统置于某种适当的状态,绝对没有必要像这样复杂化。
一只名叫tom的猫
TA贡献1906条经验 获得超3个赞
- 3 回答
- 0 关注
- 146 浏览
添加回答
举报
0/150
提交
取消