When writing programs that do computations, my overwhelming preference is
to simply write results to standard output, and to use shell redirection
to capture the output in a file. In this way, I am leveraging the shell’s
full functionality, in particular filename completion, in the most
convenient way possible. For the file format itself, I prefer simple,
column-oriented, delimiter-separated flat files. They are completely
portable, and can be read and understood by most tools. (They also
play well with the usual Unix toolset.)
But this simple approach breaks down, once a program has to write more
than one output stream: for example in the case of a simulation run, I
may want to capture periodic snapshots of the simulation itself, but also
track various calculated metrics as well. These two streams will not fit
comfortable into a single flat file. One option is to use a structured
file format, the other option is to write to multiple files
simultaneously.