I use as follows:
Plain text
For configuration - usually using YAML or .ini. Deprecated by me for most uses except when a text file is the desired result (e.g. print to text, save to text etc.)
XML
For configuration and transportation of data; e.g. export, format via XSLT etc. Good as a portable file format (e.g. SVG). Excellent manipulation tools and filters.
Databases
Main data storage from inside app/webapp. Use it all the time as storage of choice. It's reliable, robust, and you get a lot built in (transactions, referential integrity, cascading delete/update, indexes, speed). Best used with a layer, or ORM (IMO).
Single file archive (e.g. .zip)
Suitable for storing related multiple binary streams compactly, e.g. ROM images for an emulator. Best for things that don't often or never have to be updated. It is heavyweight, slow and hard to manipulate;
Binary
Only where a database is not available for storing app data. Easiest with serialization (C++). A highly tuned binary format will outperform everything else for both speed and size.
Without the translation, every Unix text-processing program would recognize just '\n'
as an end-of-line marker, and every Windows text-processing program would recognize '\r'
followed by '\n'
. (And pre-OSX Mac programs would recognize '\r'
.) And any program that writes text would have to explicitly write the local end-of-line marker, which means it would have to be aware of what OS it's running on.
And that just covers the relatively simple cases where an end-of-line is indicated by a sequence of characters. Other schemes are common (though less so these days); see IBM mainframes and VMS, for example.
With the translation, programs can just treat text as text, and we don't need three or more different "hello, world" programs.
This does sometimes cause problems when you need to process a foreign file (a Windows text file that's been copied to a Unix system, or vice versa). Cygwin, a Unix-like environment running under Windows, is a rich source of such issues. But usually the best solution is to translate the file before processing it. And most of the time, programs deal with text files that were created on the same OS anyway.
It's better to write one program that can translate between formats, than to require every program to deal with all different formats. And inevitably someone would write a tool that understand Unix and Windows formats, but breaks when confronted with an old Mac text file, and someone else would get the interpretation just a little bit wrong because the wheel they reinvented wasn't perfectly round.
Best Answer
Using
fscanf()
in itself probably explains most of it.fscanf()
has to interpret the passed-in format string, and then has to scan the input stream from the file, trying to match the specified pattern. That's actually a huge amount of work.read()
just has to read in the specified number of bytes from the file and doesn't have to do any parsing of the input. By contrast, fgets() does a little more work thanread()
since it has to watch for newlines, but it does a lot less work thanfscanf()
.