Файлы выгружаются с помощью fwrite в разных системах? - PullRequest
0 голосов
/ 03 февраля 2010

Можно ли предположить, что файл, созданный с помощью fwrite и прочитанный с использованием fread, переносим в разных системах. 32-битные / 64-битные окна, osx, linux.

//dumping
FILE *of =fopen("dumped.bin","w");
double *var=new double[10];
fwrite(var, sizeof(double), 10,FILE);
//reading
file *fo=fopen()
double *var=new double[10];
fread(var,sizeof(double),10,of);

А как насчет структур

struct mat_t{
    size_t x;
    size_t y;
    double **matrix;
}

Это портативные?

Ответы [ 5 ]

5 голосов
/ 03 февраля 2010

Краткий ответ: НЕТ

Длинный ответ:

Вы записываете двоичное представление данных.
Это не переносимо между платформами или ОС или даже компиляторами.

У всех объектов, которые вы написали, есть вещи, которые можно изменить:

int:        size and endianess.
double:     size and representation.
structure:  Each member has to be looked at individually.
            The structure itself may be padded different on different compilers.
            Or even the same compiler with different flags.
pointers:   Are meaningless even across processes on the same machine.
            All pointers have to be converted into something meaningful like
            a named object that is provided separately. The transport will then
            have to convert named objects into pointers at the transport layer
            at the destination.

У вас есть два основных варианта:

  • Потоковая передача данных.
    Это в основном преобразование структуры в текстовое представление и отправка строки. Для небольших объектов, структуры API это текущий стандартный метод межплатформенного / языкового общения (хотя данные обычно заключаются в какой-то формат, например XML или Json).
  • Преобразовать в сетевой нейтральный двоичный формат
    Для этого у нас есть htonl () и семейство функций () для преобразования целых чисел. Двойные числа сложнее и обычно конвертируются в два целых числа (значения зависят от требований к точности). Строки преобразуются в длину, за которой следует последовательность символов и т. Д. Затем каждая запись записывается в поток отдельно. Это может быть гораздо более компактным, чем потоковое (и, следовательно, эффективным). Недостатком является то, что вы тесно связываете оба конца с очень специфическим форматом, что делает решение особенно хрупким и трудным для исправления в ситуациях ошибки.
4 голосов
/ 03 февраля 2010

fwrite и fread достаточно переносимы, но у вас будут проблемы с такими вещами, как sizeof(double), которые могут различаться в разных системах. Убедитесь, что каждое двоичное поле, которое вы пишете, имеет определенный размер, который не зависит от компилятора или ОС - вы можете в значительной степени выполнить это, используя типы, которые явно задают их размер, например uint32_t.

Вам также нужно беспокоиться о порядке байтов, но есть макросы ntoh, ntohl, hton и htonl, которые вы можете использовать для замены порядка байтов, и они должны быть определены для правильной в какой бы системе вы их не компилировали.

1 голос
/ 03 февраля 2010

Если вы пишете структуры, и они не являются самодостаточными (то есть имеют указатели, подструктуры), вам гораздо лучше использовать какую-нибудь библиотеку сериализации.Существует библиотека Boost Serilization , которая использует объектно-ориентированный подход.Вывод может быть легко переключен с текстового на двоичный, что значительно упрощает отладку.

Существует также HDF5 (иерархический формат данных), набор библиотек, которые обычно используются в научных исследованиях.вычисления на некотором необычном оборудовании (не ваш стандартный x86).Я никогда не использовал это, поэтому я не могу говорить о том, насколько это легко использовать, но он будет обрабатывать огромные наборы данных (несколько ТБ).

1 голос
/ 03 февраля 2010

Этот файл точно не будет переносимым. Вот почему существуют такие вещи, как htons . Вы должны убедиться, что ваш формат файла очень четко определяет размер и порядковый номер . Поскольку отдельные типы не являются переносимыми, структуры также не являются (даже не учитывая структура упаковки ).

0 голосов
/ 03 февраля 2010

Вы забываете, что Windows предполагает, что запись в файл выполняется в текстовом режиме, поэтому вам нужно изменить "w" на "wb" во втором параметре на fwrite ()

...