我想扩展以无缓冲方式将数据写入文件的现有代码。
该代码需要一个实现io.WriteCloser
接口(interface)的编写器。因此,仅使用bufio.Writer
包装现有文件是行不通的,因为它无法实现此接口(interface)。
如何制作bufio.Writer
来实现并将必要的close调用传递给底层文件?
最佳答案
io.WriteCloser
是接口(interface):
type WriteCloser interface {
Writer
Closer
}
最终“规定”了这两种方法:
Write(p []byte) (n int, err error)
Close() error
bufio.Writer
已经具有Write()
方法,因此要使其成为WriteCloser
,只需一个Close()
方法。使用noop
bufio.Writer
方法扩展Close()
:type MyWriteCloser struct {
*bufio.Writer
}
func (mwc *MyWriteCloser) Close() error {
// Noop
return nil
}
类型
*MyWriteCloser
的值现在是WriteCloser
。这是最简单的扩展。使用它:bw := bufio.NewWriter(w)
mwc := &MyWriteCloser{bw}
尽管我们可以并且应该添加一个更有意义的
Close()
方法。由于bufio.Write
会缓存写操作,因此在声明关闭之前,应先刷新其内部缓冲区:func (mwc *MyWriteCloser) Close() error {
return mwc.Flush()
}
还要注意,由于无法关闭
bufio.Write
(不提供Close()
方法),因此不会关闭其基础io.Writer
,这仅符合io.Closer
和io.WriteCloser
接口(interface)。如果您还想关闭基础文件,则还必须存储它,并且在调用
bufio.Flush()
(以确保所有内容都写完)之后,鉴于它没有返回任何错误,您可以继续关闭该文件。它看起来像这样:
type MyWriteCloser struct {
f *os.File
*bufio.Writer
}
func (mwc *MyWriteCloser) Close() error {
if err := mwc.Flush(); err != nil {
return err
}
return mwc.f.Close()
}
使用它:
// Open a file:
f, err := os.Open("myfile.txt")
if err != nil {
panic(err) // Handle error
}
mwc := &MyWriteCloser{f, bufio.NewWriter(f)}
defer mwc.Close()
// use mwc