buffered_writer.go 1.7 KB

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