Proper choice of file stream objects
Application uses RapidXML to edit XML file. Editing is not automated and takes place occasionally: XML content is displayed in GUI and user performs some actions which change XML. Each change must be saved to disk immediately.
Loading RapidXML document object requires copying the content of the file into a string. Each change in a document is followed by copying the content of the document object back into the file.
File is used both for input and output in this example. Shall a single std::fstream
object be used for all input/output operations in this case? It would be opened once, at the application startup, used for input/output, and closed at the end of the application.
Or, shall local (temporary) instances of std::ifstream
and std::ofstream
be used whenever file input/output needs to be performed? E.g. std::ifstream
to be used at the beginning for reading the file (open, read, close); similarly, std::ofstream
instance to be used whenever DOM must be exported into the file (open, write, cl开发者_Go百科ose).
I am not concerned about performances here (due to the nature of the application) but am curious about the proper choice of file stream objects in this case.
Editing files in place when the amount of data to re-write is different from the original data is a real pain. If your file format requires data to be sequential and has no syntax for holes, then you don't really have a choice but to re-write the file (at least from the start of the modified position).
Also, there are additional constraints. If you require the data to be flushed to disk before continuing, then you might be able to use a single std::fstream
for multiple edits. Operating systems typically don't flush the file to disk even when you invoke the flush()
method on file streams. Some platforms offer non-portable solutions to really force a write. So if you need it to be flushed to disk, your best bet is to actually close the file.
Thus, especially for critical applications, I would recommend the 2nd approach (ifstream
at initial load, ofstream
at each write). I would also recommend writing to a temporary file, then moving the complete re-write to the preferred location, replacing the original files. This ensures you won't have any data loss (at least on systems that offer atomic file move).
I'd definitely favor local temporary instances of std::ifstream
and
std::ofstream
. I'm not even sure it would work otherwise; opening an
std::ofstream
empties the contents of an existing file. Just seeking
to the beginning and overwriting doesn't remove any previous contents,
and if the results of the changes shorten the file, you'll still be left
with leftover characters from the earlier contents.
精彩评论