Я пытаюсь записать и считать объект класса в и от двоичного файла в C++. Я хочу не записать элемент данных индивидуально, но записать целый объект когда-то. Для простого примера:
class MyClass {
public:
int i;
MyClass(int n) : i(n) {}
MyClass() {}
void read(ifstream *in) { in->read((char *) this, sizeof(MyClass)); }
void write(ofstream *out){ out->write((char *) this, sizeof(MyClass));}
};
int main(int argc, char * argv[]) {
ofstream out("/tmp/output");
ifstream in("/tmp/output");
MyClass mm(3);
cout<< mm.i << endl;
mm.write(&out);
MyClass mm2(2);
cout<< mm2.i << endl;
mm2.read(&in);
cout<< mm2.i << endl;
return 0;
}
Однако вывод выполнения показывает, что значение mm.i, предположительно, записанного в двоичный файл, не считано и присвоено mm2.i правильно
$ ./main
3
2
2
Так что случилось с ним?
О чем я буду знать при общей записи или чтении объекта класса в или от двоичного файла?
. Данные буферируются, поэтому он на самом деле не достиг этого файла, когда вы идете, чтобы прочитать его. Поскольку вы используете два разных объекта для ссылки на файл входа / выхода, ОС не подсказывает, как они связаны.
Вам нужно либо промойте файл:
mm.write(&out);
out.flush()
или закрыть файл (который делает неявный флеш):
mm.write(&out);
out.close()
Вы также можете закрыть файл, имея объект выходить из системы:
int main()
{
myc mm(3);
{
ofstream out("/tmp/output");
mm.write(&out);
}
...
}
Я буду повторять «Вы не должны делать это». Если вы распечатаете SIZEOF (MYC)
в коде выше, вероятно, 4, как вы ожидаете ... но попробуйте изменять чтение и запись, чтобы быть виртуальным. Когда я сделал это, он распечатывает размер 16. Эти 12 байтов являются внутренними смелостью с чувствительными значениями - и сохранение их, а затем чтение их обратно было бы, чтобы ожидать, что ценность указателя будет еще хорошо, если вы написали его и загружены снова.
Если вы хотите обойти сериализацию и отобразить память объекта C ++ непосредственно на диск, есть способы взломать это. Но правила участвуют, и это не для слабого сердца. См. POST ++ (постоянное хранение объектов для C ++) в качестве примера.
Я добавлю, что вы не проверяли FAIL ()
или () [)
() [) . Если бы вы могли знать, что вы злоупотребляете API FStream. Попробуйте снова с:
void read(ifstream *in) {
in->read((char *) this, sizeof(myc));
if (in->fail())
cout << "read failed" << endl;
}
void write(ofstream *out){
out->write((char *) this, sizeof(myc));
if (out->fail())
cout << "write failed" << endl;
}
... и посмотрите, что происходит.
Сброс необработанных данных - это ужасная идея, от нескольких угла. Это сломается еще хуже, когда вы добавите данные указателя.
Одним из предложений будет использоваться BOOST.Serialization , которая позволяет намного более надежными данными.
Ваша главная проблема - это файл не содержит содержимого, но из-за буферизации FStream. Закрыть или промойте файл.
Мой C ++ - это красивая ржавчина и очень недооценка, но вы можете взглянуть на сериализацию и нересилизацию. FAQ