<p>In the gzip package, the Reader's close method is <a href="https://github.com/golang/go/blob/76f981c8d86ec122da50a140f8843eb636ac8240/src/compress/gzip/gunzip.go#L292">https://github.com/golang/go/blob/76f981c8d86ec122da50a140f8843eb636ac8240/src/compress/gzip/gunzip.go#L292</a></p>
<p>This code calls the Close method in the <a href="https://github.com/golang/go/blob/76f981c8d86ec122da50a140f8843eb636ac8240/src/compress/flate/inflate.go#L353">flate</a> package</p>
<p>Since the Close method in the flate package doesn't actually close anything, why is it there?</p>
<hr/>**评论:**<br/><br/>joetsai: <pre><p>In the very early days of the flate package, it used goroutines to perform the decompression work such that after Read returned, the flate.Reader could continue to decompress data and the next call to Read would not block for long since it would (hopefully) just need to copy the pre-decompressed data. It did the same pattern for the compression side of things as well. The Close method was necessary to ensure that there was no goroutine leak.</p>
<p>The problem is that the io.Writer interface does not guarantee that the buffer passed to Write is safe for continual access after Read has returned. This led to race conditions with the compressor working in parallel. To fix this, Russ stripped the use of goroutines from the Writer (and the Reader, to be consistent). Since goroutines were no longer used, the Reader.Close method was no longer needed and could have been removed.</p>
<p>Technically it could have been removed since the change to synchronous compress/decompression happened before the Go1.0 release, but oops. There are still many other strange quirks left in the flate package due to it's long heritage that I'll hopefully clean up in Go1.9. However, if I could break the Go compatibilty agreement, the first thing I would do would be to make NewReader return a *flate.Reader rather than an io.ReadCloser.</p>
<p>Source: I'm one of the maintainers of flate package now.</p>
<p>P.S. It's not entirely a bad idea to have decompressors have a Close method. It's common to swap out one compression format for another for performance reasons, and sometimes the implementation swapped in is a C-wrapped version. The Close method on a Reader would be necessary to clear out allocated C memory. For example, I'm glad the zip.RegisterDecompressor function uses io.ReadClosers, so that you can safely pass in an implementation that requires post-use cleanup (either due to C allocations or goroutines) and be assured that the zip package will clean things up properly.</p></pre>lesmond: <pre><p>Yes!</p></pre>sheenobu: <pre><p>The Lesson; Dear Reader: It's there because it was put there once and now can't be removed.</p>
<p>Lets check blame... the flate decompressor struct was given a Close method in this commit: <a href="https://github.com/golang/go/commit/07acc02a29ac74e7c0b08b4cd382bf71acd262dd" rel="nofollow">https://github.com/golang/go/commit/07acc02a29ac74e7c0b08b4cd382bf71acd262dd</a></p>
<p>Before that commit, flate.NewReader returned the reading side of an io.Pipe. You can see that <a href="https://github.com/golang/go/commit/07acc02a29ac74e7c0b08b4cd382bf71acd262dd#diff-206fa45b94395c28494b1845f689e7a7L627" rel="nofollow">here</a>. This is most likely why flate.NewReader returns an io.ReadCloser. </p>
<p>The new (as of 2011) flate decompressor non-op Close method is due to the evolution of code and requirements of API compatibility. The gzip package is unaware of this and continues to use the flate reader as-is.</p></pre>
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码`
- 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传