ofstream(mode ios::out) wipes existing file blank

2019-09-15 19:41发布

The usage scenario is industrial (unstable power supply and other buggy programs/hardware). It is required that the program should come back unaffected when power is off (or blue-screen crash). OS is Windows 7 with NTFS.

I use boost::property_tree write json to record parameters to human readable text file.

boost::property_tree::write_json("logic.txt", pt);

It actually wiped the "logic.txt" sometimes, when system halt. I read the boost source file and write_json calls ofstream with default ios::out

std::basic_ofstream<typename Ptree::key_type::value_type> stream(filename.c_str());        

The problem should be ofstream wipe the existing file and leaves blank file when system fails.

Is this a known problem with ofstream? What is the most suitable solution to this ? I can think of a few:

  1. Write file to "logic_tmp.txt" first, when finished, delete "logic.txt" and rename the temp file to logic.txt.

  2. Using SQLite instead of writing to file directly. (MySQL broke some times, table required to be "repaired" when start up again, SQLite hasn't failed me yet)

any suggestion would be helpful.

1条回答
放荡不羁爱自由
2楼-- · 2019-09-15 20:33

The simple solution is your #1: write to a temporary file then rename. However, do note that for the rename to be atomic, the temporary file should be on the same filesystem. Safest would be to simply store it in the same directory. And of course you can use mkstemp() or similar to make sure you have a unique temporary filename.

The above is still not a 100% guarantee on all possible systems, because it depends on your filesystem semantics (you didn't tell us what filesystem you're using).

If you want a more bullet-proof solution, your #2 is a good idea: use SQLite. It's been tested in a lot of scenarios like you describe. See https://www.sqlite.org/testing.html

查看更多
登录 后发表回答