-
Notifications
You must be signed in to change notification settings - Fork 17.8k
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
proposal: os: File should implement io.ByteReader and io.ByteWriter #22771
Comments
My hesitation would be that if you want to read or write a single byte from/to a file it is in fact normally the right thing to do to wrap the Can you clarify what broke in the case you mentioned? |
Thanks. It's not the most convincing example since in general gob does not permit bouncing around in the stream. As the package doc explains, gob encodes types only once in the stream, so seeking in the stream while decoding from it will not work in the general case. |
Reposting my comment that Ian is replying to (I deleted it since I posted it with the wrong GitHub account): I see what you mean, it would definitely be less efficient than using I built a minimum-viable-example of the issue I encountered at https://play.golang.org/p/WuDB9zZczd |
Yeah, I realize my example use-case is not a supported or normal one. I did some digging on GitHub and found that there are a fair amount of people that are pretty much re-implementing this
In general though, I think expanding |
As Ian mentioned, I should also note that |
@ianlancetaylor hmm i read the gob package documentation, and it did not seem clear that it encodes types only once in the stream, or that doing a file.Seek would break gob.Decode. From the documentation: Is it implied that since it reads from an input stream, that the seek pointer of whatever implements that io.Reader, must point to the top of the stream? Doesn't seem like it to me, but I may have misread or glanced over something. Maybe it is the documentation that needs changing then. |
Anytime buffering is involved, it is almost always a bad idea to be seeking the underlying reader. Secondly, I don't think of that as a reasonable default to assume. If |
I'm learning a lot here, but I think this is going off into a bit of a tangent. I recognize that my |
To focus on the specific proposal: I definitely don't think we should do this because one-byte reads and writes are not efficient. I believe that the valid use cases for this is rare enough that it's better to not provide this functionality which would be ripe for misuse.
Note that bufio.Writer has Flush for those times that you want to ensure that everything has been written to the underlying writer. |
Let me preface this with saying this is my first proposal to Go and I am definitely not anywhere near an expert on the language like the others here are. I've looked for documentation on the design philosophy behind Go but the best I've found is https://golang.org/doc/faq#principles so if anyone has a better link I'd love to read it. I really appreciate all the Golang developers and other experienced Gophers being so patient with me here. My reasoning was that developers using Is the point against this that |
I would say:
|
This inefficiency can't be swept under the rug. Many packages assume that if an io.Reader implements io.ByteReader then using the ReadByte method is about as efficient as buffering the original reader. They would get much much slower if we added an inefficient ReadByte to os.File (for example, compress/bzip2, compress/flate, compress/zlib, encoding/gob, encoding/xml all do this). |
File
already implements multipleio
interfaces[0]. Implementing more lets users useFile
without having to wrap it in another reader.This is inspired by hitting a bug whereThis was a bad example, please see my newer examples at #22771 (comment)gob.Decoder
requires anio.Reader
but if it does not implementio.ByteReader
as well it will wrap it in abufio.Reader
which broke usingFile.Seek
.I already have a patch ready that would add this should this proposal be approved.
[0] Specifically
io.Reader
,io.Close
,io.ReadAt
,io.Seeker
,io.Writer
, andio.WriteAt
The text was updated successfully, but these errors were encountered: