Я бы рассмотрел определение структуры, которую более высокие уровни используют для хранения данных, немного как мини-файловая система внутри файла.
Например, даже если ваш формат файла будет хранить данные, зависящие от приложения, я бы рассмотрел определение записей/потоков и т. Д. Внутри файла таким образом, чтобы аппликационный код приложения мог понять макет файл, но, конечно, не понимают непрозрачные полезные нагрузки.
Давайте сделаем немного более конкретным. Рассмотрим обычные способы хранения данных в памяти: как правило, они могут быть сведены к смежным расширяемым массивам/спискам, графам с указателем/ссылкой и бинарным блокам данных в определенных форматах.
Таким образом, может быть полезно определить формат двоичного файла вдоль аналогичных строк. Используйте записи заголовков, которые указывают длину и состав следующих данных, будь то в виде массива (список идентично типизированных записей), ссылки (смещения на другие записи в файле) или капли данных (например, строковые данные в конкретной кодировке, но не содержащей ссылок).
Если это тщательно разработано, это может позволить использовать формат файла не только для непрерывного хранения данных за один раз, но и поэтапно по мере необходимости. Если подструктура правильно спроектирована, она может быть прикладной агностикой, но все же разрешать, например, приложение для сбора мусора, которое должно быть написано, которое понимает капли, массивы и типы опорных записей и может отслеживать файл и исключать неиспользуемые записи (т. е. записи, которые больше не указываются).
Это всего лишь одна идея. Другие места для поиска идей - это, в общем, проекты файловой системы или стратегии физического хранения реляционных баз данных.
Конечно, в зависимости от ваших требований это может быть излишним. Вы можете просто быть после двоичного формата для сохранения данных в памяти, и в этом случае подход к рассмотрению будет отмечен записями.
В этом подходе каждая часть данных имеет префикс с тегом. Тег указывает тип сразу следующих данных и, возможно, его длину и имя. Списки могут быть помечены тегом «конечного списка», который не имеет полезной нагрузки. Тег может иметь встроенный идентификатор, поэтому теги, которые не поняты, могут игнорироваться механизмом сериализации, когда он читает вещи. В этом отношении это немного похоже на XML, за исключением использования двоичных идиом.
На самом деле, XML - это хорошее место для поиска долговременной долговечности формата файла. Посмотрите на возможности использования имен. Если вы аккуратно создаете свой код для чтения и записи, должно быть возможно писать приложения, которые сохраняют местоположение и содержимое помеченных (рекурсивно) данных, которые они не понимают, возможно потому, что они были написаны более поздней версией того же приложения.
PNG - один из примеров. Другие с аналогичной структурой - это IFF (формат файлов обмена, в основном используемый на Commodore Amiga) и RIFF (например, WAV или AVI). – BlaM 2008-11-27 13:42:57