doutan1671 2017-03-30 10:49
浏览 423
已采纳

如何获得实现io.WriteCloser的bufio.Writer

I want to extend existing code that writes data to a file in an unbuffered way.

The code expects a writer that implements the io.WriteCloser interface. Therefore just wrapping the existing file with a bufio.Writer does not work, as it does not implement this interface.

How can I make a bufio.Writer to implement and pass the necessary close call to the underlaying file?

  • 写回答

1条回答 默认 最新

  • douhuan1905 2017-03-30 11:01
    关注

    io.WriteCloser is the interface:

    type WriteCloser interface {
            Writer
            Closer
    }
    

    Which ultimately "prescribes" these 2 methods:

    Write(p []byte) (n int, err error)
    
    Close() error
    

    bufio.Writer already has a Write() method, so to make it a WriteCloser, only a Close() method is needed.

    Extending bufio.Writer with a noop Close() method:

    type MyWriteCloser struct {
        *bufio.Writer
    }
    
    func (mwc *MyWriteCloser) Close() error {
        // Noop
        return nil
    }
    

    A value of type *MyWriteCloser is now a WriteCloser. This is the easiest extension. Using it:

    bw := bufio.NewWriter(w)
    
    mwc := &MyWriteCloser{bw}
    

    Although we can –and we should– add a more meaningful Close() method. As bufio.Write does buffered writes, we should flush its internal buffer before we declare it closed:

    func (mwc *MyWriteCloser) Close() error {
        return mwc.Flush()
    }
    

    Also note that since bufio.Write cannot be closed (does not provide a Close() method), this will not close its underlying io.Writer, this is just to conform to the io.Closer and io.WriteCloser interfaces.

    If you also want to close the underlying file, you also have to store it, and after calling bufio.Flush() (to make sure everything is written out), given it's not returning any errors, you may proceed to also close the file.

    This is how it could look like:

    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()
    }
    

    Using it:

    // 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
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 怀疑手机被监控,请问怎么解决和防止
  • ¥15 Qt下使用tcp获取数据的详细操作
  • ¥15 idea右下角设置编码是灰色的
  • ¥15 全志H618ROM新增分区
  • ¥15 在grasshopper里DrawViewportWires更改预览后,禁用电池仍然显示
  • ¥15 NAO机器人的录音程序保存问题
  • ¥15 C#读写EXCEL文件,不同编译
  • ¥15 MapReduce结果输出到HBase,一直连接不上MySQL
  • ¥15 扩散模型sd.webui使用时报错“Nonetype”
  • ¥15 stm32流水灯+呼吸灯+外部中断按键