Is it safe to assume:
- small size: <100KB
- medium size: <1MB
- big size: <10MB
- huge size: >10MB
?
Thanks,
Mitică
I mean the file sizes Go handles gracefully, not source files, sorry.
I know it's machine and platform dependent, but still.
Is it safe to assume:
- small size: <100KB
- medium size: <1MB
- big size: <10MB
- huge size: >10MB
?
Thanks,
Mitică
The read buffer is not the issue.
Consider the case of "jumping" inside the file, to certain bytes positions.
Looking at a "modest typical current machine", or at different other samples, from what file sizes are performance degradation for repeated ReadAt() positioning operations become noticeable?
On Saturday, January 26, 2013 1:15:43 PM UTC+2, peterGo wrote:Mitică,
It's not sfafe to assume that; it's a nonsense question.
What I'm trying, is an assessment before non-liniar processing.
peterGo: You're should be doing error handling _after_ you process the data that's returned, since the io.Reader documentation explicitly states that an implementor may either return the data read up to the point at which the error occurred along with the error, _or_ wait to return the error on the next call with no bytes having been read; anyone using Read should account for both cases by processing n before err. In theory, the last n bytes (as returned by Read) of the pagefile could contain zeroes that you're not counting.
Very interesting, thank you for that. I have a feeling this might be the source of quite a few of my bugs..
Here's my understanding....n, err := r.Read(buf)
[snip behaviour of read]
[...] func ReadN(r io.Reader, size int), []byte, err { [...]
// Returns a buffer of n bytes, or a nil buffer if we couldn't read that many// error == nil iff the buffer was successfully filled// error != nil iff the buffer was not completely filled
To state an example scenario, I'm reading some header of an arbitrary binary format, I'm some way into it, and I want to read the next 32 bytes. What's the best way to achieve that under all circumstances except unrecoverable failure? Are there cases where it's necessary to manually retry a io.ReadFull?My naive code might have looked like:buf := make([]byte, 32)_, err := io.ReadFull(fd, buf)if err != nil { ... invoke panic, or ideally do something sensible ... }
I'm guessing LimitedReader and SectionReader would be useful in this situation. It's hard to answer this question correctly without knowing the state of the reader immediately before this section of code. Maybe post an example?
On 30 January 2013 13:43, Nate Finch <nate....@gmail.com> wrote:
Here's my understanding....
[...] func ReadN(r io.Reader, size int), []byte, err { [...]
Yup, like this! I too wrote a function, then I realised there was io.ReadFull, which was supposed to do (almost exactly) this for me. Great! Except.. ReadFull doesn't behave how I thought it was supposed to?
// Returns a buffer of n bytes, or a nil buffer if we couldn't read that many// error == nil iff the buffer was successfully filled// error != nil iff the buffer was not completely filled
This sounds almost exactly like the io.ReadFull docs:
On Saturday, 26 January 2013 18:46:36 UTC, minux wrote:And it's very tricky to get code calling Read directly 100% correct.In fact, even io.ReadFull can't correctly handle the case when a
I'm often faced with wanting to read a known number of bytes into a slice, so io.ReadFull is my tool of choice (or io/ioutil.ReadAll() if I want to read to EOF). I've had many issues stemming from forgetting a check here or there (that N was what I was expecting, etc).
I had to think about the text below for quite a while before I came to the conclusion: reading is hard. This is way more subtle than I realised.So a question: What does "correct" code look like?
To state an example scenario, I'm reading some header of an arbitrary binary format, I'm some way into it, and I want to read the next 32 bytes. What's the best way to achieve that under all circumstances except unrecoverable failure? Are there cases where it's necessary to manually retry a io.ReadFull?My naive code might have looked like:buf := make([]byte, 32)_, err := io.ReadFull(fd, buf)if err != nil { ... invoke panic, or ideally do something sensible ... }
I would have assumed that either my program bails because of an unrecoverable problem (e.g, the file is short and therefore corrupted), or everything is okay and I read the expected number of bytes into buf. I'm surprised to hear if there are other possibilities - maybe this should be considered a documentation bug?Is the above code wrong? If so, under what circumstances will it fail, and how can I get this right?Is it sufficient to check (s/_/N/) N after the above code, and if we're short some bytes, am I able to perform another read, or is `fd` dead at that point?p.s. oh, and please also substitute `fd` for a socket or readable of your choice which illustrates issues with the above.
On Saturday, 26 January 2013 18:46:36 UTC, minux wrote:also note that users of io.Reader should be aware that the seemingimpossible return 0,nil and len(buf),err (err != nil) are in fact allowed.And it's very tricky to get code calling Read directly 100% correct.In fact, even io.ReadFull can't correctly handle the case when abad reader always returns len(buf), err where err != nil && err != io.EOF(ReadFull will return len(buf), and a non-nil error, violating thedocumented interface if you assume the sentence"It returns the number of bytes copied and an error if fewer bytes were read."means that whenever it returns non-nil error, n < len(buf))However, we can't ban len(buf), err return from readers as if we do,the reader is forced to keep the error until next read, and a lot of readerimplementations don't do that, so Go 1 contract will be broken.The take away is:strictly speaking, even ignoring the returned `n` from io.ReadFull isan error.
--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
buf := make([]byte, 32)_, err := io.ReadFull(fd, buf)if err != nil { ... invoke panic, or ideally do something sensible ... }If ReadFull returns an incomplete read with a nil error, that is a bug.To quote the docs: "It returns the number of bytes copied and an error if fewer bytes were read."
However, this means that calling io.ReadFull like this is definitely wrong:_, err = io.ReadFull(rd, buf)if err != nil {// handle the error without touching buf}A sad truth is that there are quite a few usages like this even in the standard library.
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.
Callers should always process the n > 0 bytes returned before
considering the error err. Doing so correctly handles I/O errors that
happen after reading some bytes and also both of the allowed EOF
behaviors.
Callers should always process the n > 0 bytes returned before
considering the error err. Doing so correctly handles I/O errors that
happen after reading some bytes and also both of the allowed EOF
behaviors.Which seems to imply that in your bad checksum case, it should return 0, ECHECKSUMbecause if the n here is non-zero, the caller of Reader must treat it as valid read data.