Description
CL 21492 added this interface during the Go 1.7 cycle. The CL description says:
io: add ReadAtSizer interface
ReadAtSizer is a common abstraction for a stateless,
concurrently-readable fixed number of bytes.
This interface has existed in various codebases for over 3 years (previously
usually named SizeReaderAt). It is used inside Google in dl.google.com
(mentioned in https://talks.golang.org/2013/oscon-dl.slide) and other
packages. It is used in Camlistore, in Juju, in the Google API Go client, in
github.com/nightlyone/views, and 33 other pages of Github search results.
It is implemented by io.SectionReader, bytes.Reader, strings.Reader, etc.
Time to finally promote this interface to the standard library and give it a
standard name, blessing it as best practice.
(A later CL renamed it to SizedReaderAt.)
I tried in CL 23374 to make os.File implement this interface, since it already implements io.ReaderAt. But the natural Size method there needs to return an error: the underlying call to find the size may fail, and that failure needs to be reported. Returning 0 is incorrect, since the caller might conclude the file is empty, returning -1 may break various slice bounds preparing for a read, and returning a very large number could result in very large allocations. In this case, there needs to be some way to report an actual error.
This seems like a general problem: ReadAt can return an error, indicating that the underlying resource can go bad, but Size cannot. There's no obvious reason why Size fundamentally can't fail. Certainly if the file were accessed over the network, trying to find the Size could easily fail. Contrast this with ReadSeeker, which is often used for non-concurrent random access to data: the Seek(0, 2) operation reports the size of the data, but also an error.
This problem with the inability to report errors suggests that, contrary to the CL description, the SizedReaderAt interface may actually not be best practice.
I'm going to remove it for Go 1.7:
it's late in the Go 1.7 cycle, there are questions about the semantics, Brad is away, and anyone who really needs this interface can continue to define it themselves for another cycle. (Also the name is still awkward.)