如何在golang中获取bufio.Writer中的缓冲数据

huangapple go评论85阅读模式
英文:

How to get the data buffered in bufio.Writer in golang

问题

当使用缓冲IO写入器(buffered io writer)时,如果发生错误,我该如何进行重试呢?
例如,我使用Write()方法写入了4096字节的数据,当缓冲写入器自动刷新数据时发生了错误。然后我想要重试写入这4096字节的数据,我该如何做呢?
似乎我必须自己保留一个4096字节的缓冲区来进行重试。否则,我将无法获取未能成功刷新的数据。
有什么建议吗?

英文:

When the buffered io writer is used, and some error occur, how can I perform the retry?
For example, I've written 4096B using Write() and an error occur when the bufwriter automatically flushes the data. Then I want to retry writing the 4096B, how I can do it?
It seems I must keep a 4096B buffer myself to perform the retrying. Othersize I'm not able to get the data failed to be flushed.
Any suggestions?

答案1

得分: 1

你需要使用一个自定义的io.Writer,它可以保存所有的数据副本,以便在重试时可以重新使用。

这个功能不是标准库的一部分,但是自己实现应该不难。

英文:

You'll have to use a custom io.Writer that keeps a copy of all data, so that it can be re-used in case of a retry.

This functionality is not part of the standard library, but shouldn't be hard to implement yourself.

答案2

得分: 1

bufio.WriterWrite(..)操作失败时,它会返回写入缓冲区的字节数(n)以及失败的原因(err)。

你可以尝试以下方法。(注意:我还没有尝试过,所以可能有一些错误,需要进行一些清理)

func writeSomething(data []byte, w *bufio.Writer) (err error) {
  var pos, written int = 0

  for pos != len(data) {
    written, err = w.Write(data[pos:])
    if err != nil {
      if err == io.ErrShortWrite {
        pos += written // 写入不完整。更新 pos 并继续循环
        continue 
      } else if netErr, ok := err.(net.Error); ok && netErr.Temporary() {
        continue // 临时错误,不更新 pos,以便再次尝试写入
      } else {
        break // 无法恢复的错误,退出循环
      }
    } else {
      pos += written
    }
  }

  return nil
}

希望对你有所帮助!

英文:

When bufio.Writer fails on a Write(..) it will return the amount of bytes written (n) to the buffer the reason why (err).

What you could do is the following. (Note I haven't yet tried this so it may be a little wrong and could use some cleaning up)

func writeSomething(data []byte, w *bufio.Writer) (err error) {
  var pos, written int = 0

  for pos != len(data) {
    written, err = w.Write(data[pos:])
    if err != nil {
      if err == io.ErrShortWrite {
        pos += written // Write was shot. Update pos and keep going
        continue 
      } else netErr, ok := err.(net.Error); ok && netErr.Temporary() {
        continue // Temporary error, don't update pos so it will try writing again
      } else {
        break // Unrecoverable error, bail
      }
    } else {
      pos += written
    }
  }

  return nil
}

huangapple
  • 本文由 发表于 2017年8月22日 18:15:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/45814915.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定