I have a program that creates several csv.Writer objects and multiplexes input between them.
As soon as the input is exhausted the program can quit, so I do this:
for _, w := range writers {
w.Flush()
}
os.Exit(0)
csv.NewWriter(io.Writer) actually initialises a bufio.Writer, so calling flush on the CSV writer just leads to a flush on the underlying bufio writer (http://golang.org/src/pkg/encoding/csv/writer.go?s=2157:2181#L85).
Now there's a need to support a flag for the writers to all produce compressed output (gzip), so I do this:// f is a file open for writing
if Opts.Compress {
writer = csv.NewWriter(gzip.NewWriter(f))
} else {
writer = csv.NewWriter(f)
}
There's a problem with this: the gzip algorithm requires an explicit Close() when the stream has finished. All that bufio.Writer.Flush() does is write all the bytes to the underlying writer - if I just treat my new writer pipeline as a single io.Writer interface value that I can pass around, there's no way to make sure I close the gzip cleanly.
The only solution I can think of is to define an interface type that encapsulates it:type WriteFlushCloser interface {
Write([]byte) (int, error)
Flush() error
Close() error
}
And then I can back that with a struct that has references to both the csv.Writer (for a Flush) and the gzip.Writer (for a Close), and the Close can just be a no-op in the case where I'm not compressing the output.
But now all my functions are dealing with some funky WriteFlushCloser thing. Surely there's a cleaner way to do this?
--
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.
I would suggest creating two composite types, one for the compressed writer and one for the uncompressed. Then make the satisfy a WriteCloser interface. Make the Close method do whatever cleanup the type needs. If you embed the csv.Writer, you won't even need to reimplement the Write method.
On 3/22/13, Daniel Bryan <dbr...@datalicious.com> wrote:
>
> Still a pity that all of my code changed to take a weird csvWriteCloser
> interface type, but I guess that's inevitable.
>
Hi,
I must be missing something but if you have just one type doing all you need, why should you use the interface csvWriteCloser?
Can't you just pass your type dualwriter?
I understand that the idea of using the interface is not having to write the "if" in the method Close(), but you are doing it.
Am I missing something?
Thanks!