Unify stream opening and closing

This cleans up some repeated code where a file would be opened, unless the
path was "-" in which the file would be bound to a stream. Deferred calls to
file.Close() also had to be cleaned up, since we don't weant to close a stream
by accident.