我注意到gzip包 internally用于读取压缩文件,而不是用于编写它们。我知道缓冲对于I/O性能很重要,那么缓冲gzip编写器的正确方法是什么?
// ignoring error handling for this example
outFile, _ := os.Create("output.gz")
// Alternative 1 - bufio.Writer wraps gzip.Writer
gzipWriter, _ := gzip.NewWriter(outFile)
writer, _ := bufio.NewWriter(gzipWriter)
// Alternative 2 - gzip.Writer wraps bufio.Writer
writer, _ := bufio.NewWriter(outFile)
gzipWriter, _ := gzip.NewWriter(writer)
// Alternative 3 - replace bufio with bytes.Buffer
buf := bytes.NewBuffer()
gzipWriter, _ := gzip.NewWriter(&buf)此外,在关闭gzip编写器或bufio编写器(或两者)之前,我是否需要刷新(),还是关闭它会自动刷新写入器?
UPDATE:我现在了解到,读写都是用gzip缓冲的。因此,缓冲一个gzip.Writer实际上是双重缓冲。@peterSO认为这是多余的。@Steven认为双缓冲可能会减少系统的数量,但建议确定基准。
发布于 2014-08-06 23:44:47
使用bufio的正确方法是为每个调用编写一个高开销的编写器。对于任何需要syscalls的作者来说都是这样。在本例中,您的"outFile“是一个OS文件,每次写入都是一个syscall。
outFile, err := os.Create("output.gz")
defer outFile.Close()
buf := bufio.NewWriter(outFile)
defer buf.Flush()
gz := gzip.NewWriter(buf)
defer gz.Close()
io.Copy(gz, src)
return在这种情况下,我们用bufio对outFile进行分组,以避免不必要的syscalls。顺序是src -> gzip ->缓冲区->文件。
现在,当我们完成编写时,我们有多个需要关闭的缓冲区。我们需要告诉gzip我们已经完成了,这样它就可以刷新其缓冲区并将最终信息写入缓冲区。然后,我们需要告诉bufio.Writer我们已经完成了,这样它就可以写出它正在为下一批写入保存的内部缓冲区。最后,我们需要告诉操作系统我们已经完成了这个文件。
这种毁灭发生在与造物相反的顺序上,所以我们可以使用延迟来使它变得更容易。在返回时,延迟器是以相反的顺序执行的,因此我们知道我们正在按正确的顺序进行冲洗,因为破坏的延迟器就在创建的函数调用的旁边。
https://stackoverflow.com/questions/25171385
复制相似问题