I’ve run quite a few times into this issue lately. I have an io.Reader
which
wraps another io.Reader
but does not offer a way to close the inner
io.Reader
.
One instance of this issue is with the bufio.Reader
type. The function below
opens the given file, peeks at the first 512 bytes to try to detect the
mime type, and then returns an io.ReadCloser
to read and then close the file.
|
|
This code does not compile because bufio.Reader
does not implement the
io.Closer
interface. Returning just an io.Reader
would not be ideal because
the opened file would get leaked, at least until the garbage collector runs.
There is an elegant pattern to fix this issue. The FuncCloser
pattern, as
opposed to io.NopCloser
allows one to add an arbitrary Close() error
function to an io.Reader
, turning it into an io.ReadCloser
.
The code above could be fixed easily by modifying the return line to:
|
|
More complex closing behavior can also be achieved by using a closure. Imagine
that file
is actually a temporary file that we must remove once we’re done
using it. We can easily close and remove it like so:
|
|
Implementing this pattern in your project is trivial:
|
|
The pattern might be useful for io.Writer
/io.WriteCloser
as well!