I’ve run quite a few times into this issue lately. I have an
io.Reader but does not offer a way to close the inner
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
io.NopCloser allows one to add an arbitrary
function to an
io.Reader, turning it into an
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
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.WriteCloser as well!