Skip to content

proposal: bufio: add Writer.UnwrittenData #59106

@wuqinqiang

Description

@wuqinqiang

Overview:
Currently, bufio.Writer does not provide a way to retrieve data that has not been successfully written. If a Flush() call fails, data in the buffer cannot be written to the underlying io.Writer.

Even if flush is called continuously, it will always fail.

func (b *Writer) Flush() error {
	if b.err != nil {
		return b.err
	}
  //....
}

We propose adding an UnwrittenData() method to allow users to retrieve data that has not been successfully written in case of a failed Flush(), enabling additional processing or retrying.

Motivation:
In some cases, Flush() may fail, for example, due to a network interruption or the underlying io.Writer closing. This could result in some data in the buffer not being written to the underlying io.Writer and being lost, which could cause inconsistencies in the application state or data loss. Therefore, users need a way to retrieve data in the buffer that has not been successfully written.

Proposal:
We propose adding an UnwrittenData() method that returns data in the buffer that has not been successfully written.

type Writer struct {
// ...
}

func (w *Writer) UnwrittenData() []byte {
return w.buf[:w.n]
}

If the data in the buffer has been successfully written to the underlying io.Writer before Flush() is called, UnwrittenData() returns an empty byte slice.

Compatibility:
This proposal has no impact on compatibility with existing code, as the new method does not modify existing interfaces or behavior.

Implementation:
The proposed method only needs to return data in the buffer that has not been successfully written, and does not need to modify any existing code or behavior.

Example:
Here is an example of how the UnwrittenData() method could be used:

	w := bufio.NewWriter(conn)
	// Write some data to the buffer
	w.WriteString("hello")
	w.WriteString("world")

	// Try to write to the underlying io.Writer, retrieve any unwritten data on failure and handle it
	if err := w.Flush(); err != nil {
		unwrittenData := w.UnwrittenData()
		log.Printf("Unwritten data: %v\n", unwrittenData)
		// Try to rewrite unwritten data by conn
		if _, err := conn.Write(unwrittenData); err != nil {
			log.Printf("Write unwritten data failed: %v\n", err)
		}
	}

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions