Я работаю над проблемой в Программировании Жемчужин - в частности, над реализацией программы, которая сортирует файл, содержащий не более 10 000 000 целых чисел (Столбец 1, Проблема 3). Поскольку в книге не указано, как данные должны храниться в файле, я рассматриваю возможность хранения целых чисел в виде необработанных байтов (есть некоторые другие ограничения, которые делают необработанные байты хорошим вариантом). Я никогда раньше не работал на таком низком уровне, поэтому я хочу знать, есть ли что-то опасное, на что я должен обратить внимание. Нужно ли беспокоиться о случайном использовании какой-либо последовательности конца файла, когда я, например, записываю необработанные байты в файл?
Редактировать:
Теперь я понимаю, насколько широк мой вопрос. Я действительно имел в виду проблемы более катастрофического характера, такие как случайная перезапись других файлов на диске. Извините, я не был яснее изначально.
Ответы:
Единственная опасность, с которой вы столкнетесь, - это маленькая или большая последовательность (независимо от того, записан ли самый старший или младший байт первым). Однако, если вы остаетесь в той же среде, проблем не будет. кроме общего обеспечения написания / разбора туда и обратно.
Файловая система предназначена для обработки любой последовательности байтов.
источник
Нет, на самом деле это то, сколько форматов файлов работает. Типичные примеры бинарных файлов, таких как это, включают изображения и музыкальные / аудио файлы.
Чтобы сохранить целостность файла и данных, прочитанных из него, обязательно следуйте этим рекомендациям:
Конкретные детали могут различаться в зависимости от платформы, платформы и языка, но это должно охватывать основные «ошибки» с файловым вводом / выводом.
источник
int
может быть от 2 до 8 или более байтов (на самом деле октеты).int
на двух разных машинах могут рассматриваться разные типы данных.В дополнение ко всем уже упомянутым ошибкам, если вы создаете новый двоичный формат файла, а не считываете и записываете данные в существующем формате, абсолютно необходимо включить заголовок файла : блок данных в самом начале файла, который однозначно определяет формат файла и записывает любые метаданные, которые могут потребоваться.
Хорошие заголовки файлов включают как минимум три вещи:
« Магическое число », по крайней мере, четыре байта. Магическое число ДОЛЖНО быть rfc2119 быть самыми первыми N байтами в файле, НЕ ДОЛЖНО использоваться для любого другого формата файла, который вы можете найти, и ДОЛЖНО содержать по крайней мере один байт, который не является печатаемым символом ASCII. Смотрите спецификацию PNG, чтобы узнать, как создать действительно тщательное магическое число. Посмотрите исходный код
file(1)
команды для базы данных существующих магических чисел, которая является настолько полной, насколько вы, вероятно, найдете.Смысл магического числа в том, чтобы однозначно пометить внутриполосный файл его форматом. Если вы не включили магическое число или это не первое, что есть в файле, вы рискуете из-за того, что программы ошибочно идентифицируют ваш файл как файл другого типа, что приводит к потере данных, обнаружению вирусов и другим подобным катастрофы.
Указание версии формата файла. Даже если вы думаете, что вам никогда не придется кардинально пересматривать формат файла, задайте следующие два байта после магического числа
00 00
и задокументируйте, что это 16-битный номер версии с определенным порядком байтов (в зависимости от того, что вам нравится, но выберите один и придерживаться его по всему файлу ) и будет увеличиваться, если значение последующих данных радикально изменится. Ваше будущее я будет вам благодарен.(Спецификация PNG здесь использует другой маршрут, определяя, что форматы чанков заморожены, и что все будущие изменения в формате будут принимать форму новых типов чанков. Это также верно, но я рекомендую простой подход «магическое число + номер версии» для новички в обработке двоичных данных. Люди, разработавшие PNG, опирались на многолетний опыт работы с форматами изображений.)
Какой-то механизм встраивания произвольных метаданных в файл. Это может быть так же просто, как если бы следующие два байта представляли собой 16-битное смещение от конца заголовка до начала фактических данных, а все промежуточное значение должно интерпретироваться как пары ключ-значение UTF-8, как в RFC 822 (то есть "
Tag: value\n
" - если вы идете по этому маршруту, я рекомендую не допускать складывания длинных линий). Опять же, PNG значительно умнее.источник
Разные архитектуры имеют разные представления для целых чисел. Основной риск здесь заключается в сохранении байтового представления целого числа в машине A, а затем в попытке прочитать его обратно и интерпретировать содержимое как целые числа в машине B. Если машины A и B имеют разные размеры для целых чисел и / или различные порядковые номера , вы ' Скорее всего, вызовет неопределенное поведение (например, в C) или исключение.
Поскольку это всего лишь пример программирования, а не «настоящая» программа, на самом деле это не проблема. Если бы это была настоящая программа, использование собственного двоичного формата для конкретного приложения, как правило, не очень хорошая идея; есть более эффективные решения, такие как SQLite или форматы сериализации на основе строк, такие как JSON, YAML, XML и т. д. Для одиночных значений достаточно превратить их в строку; для простых списков вы можете сохранить одну строку на строку и просто разделить ввод на новые строки, когда вы прочитаете его обратно.
источник