mmap с прямым порядком байтов и прямым порядком байтов

Если я использую mmap для записи uint32_t, возникнут ли у меня проблемы с соглашениями о прямом/прямом порядке байтов? В частности, если я запишу некоторые данные mmap на машине с прямым порядком байтов, возникнут ли у меня проблемы при попытке прочитать эти данные на машине с прямым порядком байтов?


person Sam Lee    schedule 22.06.2009    source источник


Ответы (2)


Если вы используете mmap, вы, вероятно, обеспокоены скоростью и эффективностью. В основном у вас есть несколько вариантов.

  1. Оберните все операции чтения и записи функциями htonl, htons, ntohl, ntohs. Вызов порядка htonl (от хоста к сети) в Windows преобразует данные с прямого порядка байтов в прямой. На других архитектурах это будет noop. Эти преобразования имеют накладные расходы, но в зависимости от ваших операций они могут быть или не быть значительными. Насколько я знаю, это подход, используемый SQLite
  2. Другой вариант — всегда записывать данные в формате хоста и предоставлять подпрограммы, если пользователям необходимо перенести свои данные между платформами. Базы данных обычно читают и записывают данные в формате хоста, но предоставляют такие инструменты, как bcp, которые записывают либо в ASCII, либо в сетевом порядке байтов.
  3. Вы можете пометить заголовок вашего файла знаком порядка байтов. Когда ваша программа запустится, она сравнит свой порядок байтов с порядком в файле и при необходимости предоставит любой перевод. Это часто хорошо для простых форматов данных, таких как UTF-16, но не для форматов, в которых у вас есть несколько типов переменной длины.

Кроме того, если вы делаете такие вещи, как предоставление префиксов длины или смещений файлов, у вас может быть смесь 32-битных и 64-битных указателей. 32-битная платформа не может создать представление mmap размером более 4 ГБ, поэтому маловероятно, что вы будете поддерживать размеры файлов более 4 ГБ. Такие программы, как rrdtool, используют этот подход и поддерживают гораздо большие размеры файлов на 64-битных платформах. Это означает, что ваш двоичный файл не будет совместим между платформами, если вы используете размер указателя платформы внутри вашего файла.

Я рекомендую заранее игнорировать все проблемы с порядком байтов и спроектировать систему так, чтобы она быстро работала на вашей платформе. Если/когда вам нужно перенести данные на другую платформу, выберите самый простой/быстрый/наиболее подходящий способ сделать это. Если вы начнете с попытки создать независимый от платформы формат данных, вы, как правило, будете делать ошибки, и вам придется вернуться и исправить эти ошибки позже. Это особенно проблематично, когда 99% данных имеют правильный порядок байтов, а 1% — неправильный. Это означает, что исправление ошибок в вашем коде преобразования данных приведет к поломке существующих клиентов на всех платформах.

Прежде чем писать код для поддержки нескольких платформ, вам понадобится многоплатформенная тестовая установка.

person brianegge    schedule 22.06.2009
comment
У нас похожие проблемы, за исключением того, что мы решили, что порядок байтов Intel является наиболее естественным способом хранения данных: почти все наши клиенты используют серверы Linux (Intel) или серверы Windows (конечно, Intel). Big endian выходит из моды. - person Tim Cooper; 10.09.2009

да.

mmap сопоставляет необработанные данные файла с адресным пространством процесса. Он ничего не знает о том, что представляют собой необработанные данные, не говоря уже о том, чтобы попытаться преобразовать их для вас. Если вы сопоставляете один и тот же файл с архитектурами с разным порядком байтов, вам придется самостоятельно выполнять все необходимые преобразования.

В качестве переносимого формата данных между компьютерами я бы рассмотрел что-то более высокого уровня абстракции, такое как JSON или даже XML, которое не привязывает формат данных к конкретной реализации. Но это действительно зависит от ваших конкретных требований.

person laalto    schedule 22.06.2009