Запишите и считайте объект класса в и от двоичного файла

Я пытаюсь записать и считать объект класса в и от двоичного файла в 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  

Так что случилось с ним?

О чем я буду знать при общей записи или чтении объекта класса в или от двоичного файла?

14
задан Jendas 17 October 2014 в 13:38
поделиться

4 ответа

. Данные буферируются, поэтому он на самом деле не достиг этого файла, когда вы идете, чтобы прочитать его. Поскольку вы используете два разных объекта для ссылки на файл входа / выхода, ОС не подсказывает, как они связаны.

Вам нужно либо промойте файл:

mm.write(&out);
out.flush()

или закрыть файл (который делает неявный флеш):

mm.write(&out); 
out.close()

Вы также можете закрыть файл, имея объект выходить из системы:

int main()
{
    myc mm(3);

    {
        ofstream out("/tmp/output");
        mm.write(&out); 
    }

    ...
}
11
ответ дан 1 December 2019 в 12:26
поделиться

Я буду повторять «Вы не должны делать это». Если вы распечатаете 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;
}

... и посмотрите, что происходит.

2
ответ дан 1 December 2019 в 12:26
поделиться

Сброс необработанных данных - это ужасная идея, от нескольких угла. Это сломается еще хуже, когда вы добавите данные указателя.

Одним из предложений будет использоваться BOOST.Serialization , которая позволяет намного более надежными данными.

Ваша главная проблема - это файл не содержит содержимого, но из-за буферизации FStream. Закрыть или промойте файл.

9
ответ дан 1 December 2019 в 12:26
поделиться

Мой C ++ - это красивая ржавчина и очень недооценка, но вы можете взглянуть на сериализацию и нересилизацию. FAQ

1
ответ дан 1 December 2019 в 12:26
поделиться
Другие вопросы по тегам:

Похожие вопросы: