Вероятно, существует ряд библиотек, которые обрабатывают определенные форматы файлов, например, варианты tar
, но не те, которые будут адаптированы к вашему конкретному формату заголовка.
Вам нужно будет решить,во-первых, имеют ли ваши метаданные фиксированный или переменный размер.
Если это фиксированный размер, относительно легко пропустить столько байтов в начале, записать остаток файла, а затем перемотатьи заполните метаданные.Если в начале известны только части переменного размера, вы можете справиться с ними практически одинаково - напишите первую версию, затем вернитесь назад, когда закончите, и напишите окончательную версию.
Если вы этого не сделаетезнать размер переменного материала до конца, вы в некотором затруднении.Вы, вероятно, в конечном итоге пишете временный файл с большей частью файла, затем, когда вы закончите и знаете все метаданные переменного размера, вы записываете заголовок метаданных в новый (последний) файл, а затем копируете временный файл послеметаданные.
Обратите внимание, что вы должны поместить размер (длину) имени файла перед фактическим именем файла в данных на диске.Затем вы можете прочитать, насколько велико имя, выделить нужное место и прочитать правильный объем данных.Размещение длины имени файла после имени файла на самом деле не очень помогает.
Вам также нужно подумать, будет ли ваш заголовок двоичными данными или текстом.Компонент имени файла будет текстовым, но число может быть 2-байтовыми или 4-байтовыми двоичными значениями или эквивалентными значениями переменной длины ASCII (в виде простого текста).Обычно легче отлаживать текстовые представления, но более вероятно, что вам понадобятся данные переменной длины, если вы используете текст.Однако вы всегда можете использовать фиксированный размер с пустым отступом.Еще одно преимущество текста над двоичным - то, что текст переносим между машинными архитектурами, тогда как двоичный поднимает вопросы о машинах с прямым порядком байтов по сравнению с машинами с прямым порядком байтов и т. Д.
Вам также следует рассмотреть возможность использования«магическое число», позволяющее идентифицировать, что файл содержит правильные данные.'Number' может быть строкой ASCII, например !<arch>\n
, используемой в некоторых версиях заголовков ar
.Или %PDF-1.3\n
, используемый в начале файла PDF.Сказав это, tar
в значительной степени уходит без магического числа в первых байтах, но это необычный дизайн в наши дни.Программа file
много знает о магических числах.Его данные иногда можно найти в файле - например, в /usr/share/file
для Mac OS X.
Не могли бы вы объяснить каким-нибудь примером?
Один формат файла, с которым я имею дело, предназначен для сообщений, обозначаемых 32-битным (подписанным) числом, с переменной длиной сообщений и, следовательно, смещениями.Файл написан в платформо-нейтральном, но двоичном формате.Числа пишутся с прямым порядком байтов, сначала MSB.Номера сообщений в настоящее время ограничены диапазоном ± 99 999 (так что в системе в целом может поместиться чуть менее 200 000 сообщений).
Заголовок файла содержит:
- 2-байтовое (без знака) магическое число
- 2-байтовое (без знака) количество сообщений, содержащихся в файле, N
За ним следует N записей, каждаяиз которых описывает сообщение:
- 4-байтовый (подписанный) номер сообщения
- 2-байтовая (без знака) длина сообщения
- 4-байтовое (без знака) смещениек началу сообщения
N записей расположены в отсортированном порядке номера сообщения, но не требуется, чтобы номера сообщений были смежными.Пропущенные числа просто отсутствуют.
После N записей следуют фактические тексты сообщений, каждый из которых состоит из соответствующего количества байтов, идентифицированных соответствующей записью, плюс ASCII NUL '\0'
байт.
Когда файл генерируется, текст каждого сообщения записывается в промежуточный файл в порядке обработки, записывая смещение сообщения в файле.Неважно, прочитаны или написаны сообщения по порядку;все, что имеет значение, - то, что смещение от конца заголовка зарегистрировано в записи заголовка.Как только все сообщения будут прочитаны, находящиеся в памяти копии файловых записей могут быть отсортированы в числовом порядке, и окончательный файл может быть записан.Сначала есть магическое число и количество сообщений;затем N записей, описывающих сообщения;сопровождаемый текстом сообщений, скопированных из промежуточного файла.
Чтение номера сообщения M достаточно просто.Вы делаете бинарный поиск по N записям, чтобы найти запись для M. Если ее там нет, пусть будет так - это ошибка.Если он есть, вы знаете, где его найти в файле и как долго он находится.
Тот факт, что данные в фиксированном, но двоичном формате, на самом деле ничего не усложняет.Вы используете одни и те же функции на машинах с прямым и прямым порядком байтов для считывания числа в собственный формат.Теоретически, вы можете оптимизировать для машины с прямым порядком байтов, но только если у машины нет проблем с недостаточно выровненными данными.Проще забыть, что оптимизация возможна и просто везде использовать один и тот же код.
Если описанный выше формат был преобразован в текстовый формат, то он, вероятно, будет иметь 8 байтов (скажем)зарезервировано для магического числа (которое может быть 7-буквенной строкой, за которой следует новая строка), а 6 байтов зарезервировано для количества сообщений (5 цифр плюс символ новой строки).Каждая из записей сообщения может быть зарезервирована 6 байтами для номера сообщения (± 99,999 для номера), плюс пробел, плюс 4 байта для длины (максимум, 8 КБ) плюс пробел, а также смещение в 8 байтов (7 цифр)плюс перевод строки).
MAGICNO
12345
-99999 8000 0000000
-90210 38 0008000
...
Опять же, преимущество текстового файла в удобочитаемости заключается в том, что вы можете легко просмотреть файл и понять смысл данных.
Вы можетеесть бесконечные вариации на эту тему.