buffered_writer.go 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. package buf
  2. import "io"
  3. // BufferedWriter is an io.Writer with internal buffer. It writes to underlying writer when buffer is full or on demand.
  4. // This type is not thread safe.
  5. type BufferedWriter struct {
  6. writer io.Writer
  7. buffer *Buffer
  8. buffered bool
  9. }
  10. // NewBufferedWriter creates a new BufferedWriter.
  11. func NewBufferedWriter(rawWriter io.Writer) *BufferedWriter {
  12. return &BufferedWriter{
  13. writer: rawWriter,
  14. buffer: NewLocal(1024),
  15. buffered: true,
  16. }
  17. }
  18. func (v *BufferedWriter) Write(b []byte) (int, error) {
  19. if !v.buffered || v.buffer == nil {
  20. return v.writer.Write(b)
  21. }
  22. nBytes, err := v.buffer.Write(b)
  23. if err != nil {
  24. return 0, err
  25. }
  26. if v.buffer.IsFull() {
  27. if err := v.Flush(); err != nil {
  28. return 0, err
  29. }
  30. if nBytes < len(b) {
  31. if _, err := v.writer.Write(b[nBytes:]); err != nil {
  32. return nBytes, err
  33. }
  34. }
  35. }
  36. return len(b), nil
  37. }
  38. // Flush writes all buffered content into underlying writer, if any.
  39. func (v *BufferedWriter) Flush() error {
  40. defer v.buffer.Clear()
  41. for !v.buffer.IsEmpty() {
  42. nBytes, err := v.writer.Write(v.buffer.Bytes())
  43. if err != nil {
  44. return err
  45. }
  46. v.buffer.SliceFrom(nBytes)
  47. }
  48. return nil
  49. }
  50. // IsBuffered returns true if this BufferedWriter holds a buffer.
  51. func (v *BufferedWriter) IsBuffered() bool {
  52. return v.buffered
  53. }
  54. // SetBuffered controls whether the BufferedWriter holds a buffer for writing. If not buffered, any write() calls into underlying writer directly.
  55. func (v *BufferedWriter) SetBuffered(cached bool) error {
  56. v.buffered = cached
  57. if !cached && !v.buffer.IsEmpty() {
  58. return v.Flush()
  59. }
  60. return nil
  61. }