-
Notifications
You must be signed in to change notification settings - Fork 18k
io: improve Reader documentation relating to EOF and zero-length []byte #10182
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
The documentaion is correct. The example is wrong. In the example (http://play.golang.org/p/b7X-Te_ltg), the first Read does not encounter EOF: r.Read(make([]byte, len(text))) EOF will not happen until a Read with len(p) > 0. In the example, the regardless condition has not been met; it's not "at the end of the input stream." |
If you define EOF that way, there is no way for Read to return
n, EOF when n == len(p).
Why there is a difference between len(p) == n or n + 1?
Put it another way, is returning n, EOF when len(p) == n a valid
behavior of a reader? If not, why? If the Reader know that it only
has len(p) bytes left, why forbid it to return EOF when it could
potentially save another call to Read?
|
A convenient IO model is: while (Read(buf) == nil) { For example, bufio.Scanner. EOF is not signaled until after all data has been read. For example, I have a read/write file or buffer that contains 10 bytes and I read 10 bytes, I don't have EOF. I'll append some more data before the next read. Don't read ahead to determine EOF. Go has a complicated io.Reader model which has two allowable EOF behaviours. "When Read encounters an error or end-of-file condition after successfully reading n > 0 bytes, it returns the number of bytes read. It may return the (non-nil) error from the same call or return the error (and n == 0) from a subsequent call. An instance of this general case is that a Reader returning a non-zero number of bytes at the end of the input stream may return either err == EOF or err == nil. The next Read should return 0, EOF regardless." Packages strings, bytes.Buffer, and bufio Readers don't return EOF until after there are no more bytes left to read. To see this behaviour, see DanK's earlier example, not the abbreviated one he posted here: http://play.golang.org/p/JwhBtBPbcM const text = "Hello, playground" // len(text) == 17 Output: 17 Which works as documented (http://golang.org/pkg/io/#Reader). |
At which point in the set of reads below is the point time there are no more bytes to read? I would claim it is after the first read. On 17/03/2015, at 6:55 PM, "peterGo" <notifications@github.commailto:notifications@github.com> wrote: Packages strings, bytes.Buffer, and bufio Readers don't return EOF until after there are no more bytes left to read. To see this behaviour, see DanK's earlier example, not the abbreviated one he posted here: http://play.golang.org/p/JwhBtBPbcM const text = "Hello, playground" // len(text) == 17 |
You yourself do so with in the CL. Consider the case of len(text)==len(p)==0. Further, where the following case was once covered by the docs, it is now undefined:
|
On Tue, Mar 17, 2015 at 8:57 AM, sabroad notifications@github.com wrote:
I don't understand. My CL clarifies that it's always valid to return 0, In your example, the first line can still return len(text), EOF, and that the change is that the 2nd call is allowed to return 0, EOF or 0, nil. Ideally, you should never pass a zero-length []byte to Read. It's all. |
Since the addition of text has been rejected, an alternative would be to remove the regardless clause to become, "The next Read should return 0, EOF." I take @robpike's point that the final paragraph allows returning 0, nil when len(p) == 0. However, given that the regardless is unnecessary and so easily read as an emphatic (I actually still find it hard to read otherwise even with the external commentaries), its presence muddies the clarity of the documentation by making the reading "The next Read should return 0, EOF regardless [of all other conditions]." |
CL https://golang.org/cl/11674 mentions this issue. |
The documentation for io.Reader states that a Read following a Read that has returned a non-zero number of bytes at the end of the input stream "should return 0, EOF regardless."
This is not what {bytes,strings}.Reader do:
http://play.golang.org/p/b7X-Te_ltg
If the "regardless" were weakened to specify "for non-zero length []byte" the documentation would match the current behaviour. (I think allowing a return of 0, io.EOF for zero-length []byte should be retained).
See https://groups.google.com/d/topic/golang-nuts/hdVJF0hU2o8/discussion for discussion.
The text was updated successfully, but these errors were encountered: