Однажды понадобилось иметь персистентную коллекцию неких записей. В процессе работы программы записи могут изменяться, удаляться, добавляться. Держать для неё отдельную СУБД - это как из пушки по воробъям, так что просто завёл файл. Встал вопрос как организовать с ним работу. Я выделил три условия:
1) С одной стороны размер этого файла не очень гигантский в том смысле, что при старте программа зачитывает его целиком в оперативку. Пусть программа стартует медленно, зато работает быстро.
2) С другой стороны его размер достаточно велик для того чтобы при изменении одной или нескольких записей перезаписывать файл целиком сбрасывая все записи из оперативки на диск. Жесткий диск может интенсивно использоваться другими программами работающими на этом же компьютере, поэтому полная перезапись файла может занять несколько секунд.
3) Если во время записи в файл произойдёт авария (выключение питания, падение программы), то данные не должны серьёзно испортиться. При рестарте программа перечитывая файл должна сама исправить ошибки в файле.
Хотелось бы узнать кто как поступил бы в этой ситуации.
Я организовал работу с этим файлом так.
Каждая запись снабжается уникальным идентификатором. Данные в файле представляют собой набор команд двух типов:
1) добавить или перезаписать запись с таким-то идентификатором такими-то значениями,
2) удалить запись с таким-то идентификатором.
Программа стартует, читает файл и выполняет команды; после выполнения всех команд в оперативной памяти получается итоговый набор записей. Когда в процессе работы программы какая-то запись удаляется, то в конец того файла дописывается команда "удалить запись с таким-то идентификатором". Когда какая-то запись добавляется или изменяется, то в конец файла дописывается команда "добавить или перезаписать запись с таким-то идентификатором такими-то значениями". То есть во время работы программы в файл дописываются только изменения -- это очень быстро (правда занимает больше места на диске). Важно что запись всегда идёт только в конец файла. Если во время записи данных в файл произойдёт авария, то при рестарте программа дочитав до этого места обнаружит ошибку в формате данных и перезапишет файл автоматически удалив эту ошибку. Ошибка может быть только в конце файла! Если при старте программа прочитав файл обнаруживает, что количество команд в нём более чем в два раза превышает итоговое количество записей, то она перезапишет файл (тем самым уменьшит его размер более чем в 2 раза). Перезапись осуществляется естественно сначала во временный файл, а затем выполняется (как бы атомарная) замена старого файла новым.