Friday, April 26, 2024
HomeGolangIn another way habits on studying the final bytes on two type...

In another way habits on studying the final bytes on two type of reader: gzip.Reader and bytes.Reader – Getting Assist


I discovered that, for 2 type of reader: gzip.Reader and bytes.Reader, they’ve in another way habits on studying the final bytes, perhaps I ought to create a difficulty on github?

Element on following

For gzip.Reader, it return 1 and an EOF for final byte learn, however for bytes.Reader, it return 1 and nil(error). I write this codes: Go Playground – The Go Programming Language

a operate like this

func compareReader(r, b io.Reader) error {
	var bufa [1]byte
	var bufb [1]byte
	for {

		na, erra := r.Learn(bufa[:])
		nb, errb := b.Learn(bufb[:])

		if erra == nil && errb == nil && na == nb && bufa[0] == bufb[0] {
			proceed
		}
		if erra == errb && erra == io.EOF {
			return nil
		}
		if erra != nil {
			if erra == io.EOF && errb != io.EOF {
				return fmt.Errorf("reader b has extra information than a")
			}
			return fmt.Errorf("learn on a error: %s", erra)
		}
		if errb != nil {
			if errb == io.EOF && erra != io.EOF {
				return fmt.Errorf("reader a has extra information than b")
			}
			return fmt.Errorf("learn on b error: %s", erra)
		}
		return nil
	}
}

I don’t care about any factor like POSIX , linux man web page, or some other, I simply suppose that every one std lib must be handled in accordance with uniform requirements.

And since the caller solely know that that is an io.Reader, he doesn’t care the underlying implement of this reader.

The documentation of io.Reader says that what you’re seeing is anticipated habits for some implementations. Particularly from the third paragraph:

When Learn encounters an error or end-of-file situation after efficiently studying n > 0 bytes, it returns the variety of bytes learn. It could return the (non-nil) error from the identical name or return the error (and n == 0) from a subsequent name. An occasion of this common case is {that a} Reader returning a non-zero variety of bytes on the finish of the enter stream could return both err == EOF or err == nil. The following Learn ought to return 0, EOF.

Although you could not care about POSIX or some other OS interface requirements, that doesn’t change the truth that the underlying working system operating your Go code does comply with POSIX or another (perhaps inside/proprietary) commonplace and that the underlying OS-level name to learn from a file, community socket, and many others., may learn to the tip of the file and never return an EOF. When you’re studying from a TCP socket, for instance, you won’t know that you just’ve reached the tip of file till the connection is closed. Your first learn may learn n bytes and then you definately sit and wait till the connection is closed at which level you learn 0 extra bytes and simply get an EOF.

Alternatively, when studying a file, it may be advantageous to return the final chunk of the file from learn and an EOF on the similar time as an alternative of 1 name to learn the final chunk and no error, and one other name to learn 0 bytes and an EOF as a result of it saves a context change to the OS to retrieve the EOF.

So, tl;dr: Submitting a difficulty to the Go workforce is not going to resolve your situation. I’d advocate as an alternative:

  1. Change your code to work with the zero and non-zero bytes learn EOF circumstances

  2. Use or create an abstraction to translate one state of affairs into the opposite:

There’s one other commonplace interface known as io.ByteReader that’s meant to learn singe bytes at a time. You possibly can verify to see if b and r implement that interface and wrap them into it if not:

b2, okay := b.(io.ByteReader)
if !okay {
    b2 = bufio.NewReader(b)
}

// similar for r

// this:
//	na, erra := r.Learn(bufa[:])
//	nb, errb := b.Learn(bufb[:])

// modifications to:
ba, erra := r2.ReadByte()
bb, errb := b2.ReadByte()

Implementations of this interface don’t combine efficiently studying bytes with errors; If there’s an error, then no bytes had been learn and if any bytes had been learn, there are not any errors.

1 Like

Thanks for such an in depth reply, after studying, I efficiently perceive it !

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments