buffered_writer.go 1.8 KB

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