buffered_writer.go 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  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. // Write implements io.Writer.
  19. func (w *BufferedWriter) Write(b []byte) (int, error) {
  20. if !w.buffered || w.buffer == nil {
  21. return w.writer.Write(b)
  22. }
  23. nBytes, err := w.buffer.Write(b)
  24. if err != nil {
  25. return 0, err
  26. }
  27. if w.buffer.IsFull() {
  28. if err := w.Flush(); err != nil {
  29. return 0, err
  30. }
  31. if nBytes < len(b) {
  32. if _, err := w.writer.Write(b[nBytes:]); err != nil {
  33. return nBytes, err
  34. }
  35. }
  36. }
  37. return len(b), nil
  38. }
  39. // Flush writes all buffered content into underlying writer, if any.
  40. func (w *BufferedWriter) Flush() error {
  41. defer w.buffer.Clear()
  42. for !w.buffer.IsEmpty() {
  43. nBytes, err := w.writer.Write(w.buffer.Bytes())
  44. if err != nil {
  45. return err
  46. }
  47. w.buffer.SliceFrom(nBytes)
  48. }
  49. return nil
  50. }
  51. // IsBuffered returns true if this BufferedWriter holds a buffer.
  52. func (w *BufferedWriter) IsBuffered() bool {
  53. return w.buffered
  54. }
  55. // SetBuffered controls whether the BufferedWriter holds a buffer for writing. If not buffered, any write() calls into underlying writer directly.
  56. func (w *BufferedWriter) SetBuffered(cached bool) error {
  57. w.buffered = cached
  58. if !cached && !w.buffer.IsEmpty() {
  59. return w.Flush()
  60. }
  61. return nil
  62. }