Cериализация для начинающих - Часть 1
ОГЛАВЛЕНИЕ
Это руководство описывает легкий способ перевода простого объекта в последовательную форму.
Данная статья является первой частью руководства по сериализации, состоящего из трех частей.
- Часть 1 является введением в основы сериализации.
- Часть 2 объясняет, как обрабатывать чтение данных из неисправных хранилищ данных и поддерживать контроль версий.
- Часть 3 описывает, как переводить в последовательную форму сложные объекты.
Сериализация - это процесс записи или чтения объекта на или из постоянного носителя информации, такого как дисковый файл. Сериализация объекта требует трех составляющих:
- Объект CFile, представляющий файл данных.
- Объект CArchive, обеспечивающий контекст сериализации.
- Объект, подвергающийся сериализации.
Шаг 1 – Открытие файла данных
Чтобы сериализовать объект в файл "foo.dat", откройте файл с соответствующим режимом доступа. В данном примере файл открывается в режиме монопольного доступа для чтения/записи.
// Открываем файл "foo.dat"
CFile* pFile = new CFile();
ASSERT (pFile != NULL);
if (!pFile->Open ("foo.dat", CFile::modeReadWrite | CFile::shareExclusive)) {
// Обрабатываем ошибку
return;
}
Шаг 2 – Подключение архива
Затем к файлу подключается объект CArchive. Архив предоставляет эффективный канал связи с постоянным хранилищем. Вместо прямого чтения из файла или записи в файл вы сериализуете данные в архив или из архива. Архиву необходимо знать, собираетесь ли вы его использовать для чтения или для записи данных. В этом примере осуществляется запись данных.
// Создание архива ...
bool bReading = false; // ... для записи
CArchive* pArchive = NULL;
try
{
pFile->SeekToBegin();
UINT uMode = (bReading ? CArchive::load : CArchive::store);
pArchive = new CArchive (pFile, uMode);
ASSERT (pArchive != NULL);
}
catch (CException* pException)
{
// Обработка ошибки
return;
}
Шаг 3 – Сериализация объекта
Сериализация объекта выполняется с помощью вызова его метода serialize(). serialize() – это всего лишь созданный программистом метод. Он не имеет никакого отношения к объекту MFC CObject::Serialize(). Также вам не нужно порождать ваш объект с помощью CObject. Метод serialize() принимает указатель на CArchive и возвращает информацию о состоянии в виде целого числа.
int CFoo::serialize
(CArchive* pArchive)
{
int nStatus = SUCCESS;
// Сериализация данного объекта ...
...
return (nStatus);
}
Фактическая процедура сериализации выполняется быстро. При этом не мешает разобраться с парой важных моментов:
- Такой же метод CFoo::serialize() используется для чтения/записи объекта из/в постоянное хранилище.
- CFoo::serialize() не знает ничего о файле, к которому получает доступ.
Предположим, что CFoo представляет собой запись о сотруднике, содержащую пару элементов данных.
class CFoo
{
// Конструктор/деструктор
public:
CFoo::CFoo();
virtual CFoo::~CFoo();
// Методы
public:
int serialize (CArchive* pArchive);
// Элементы данных
public:
CString m_strName; // имя сотрудника
int m_nId; // идентификатор сотрудника
};
Потоковые операторы CArchive << и >> используются для чтения/записи элементов данных из/в архив. CArchive знает, как сериализовать простые типы данных, такие как int, float, DWORD, и объектные, такие как CString. Архив также знает, в режиме чтения или записи он находится. Вы можете запросить его режим с помощью вызова CArchive::IsStoring(). Метод сериализации CFoo можно написать таким образом:
int CFoo::serialize
(CArchive* pArchive)
{
int nStatus = SUCCESS;
// Сериализация объекта ...
ASSERT (pArchive != NULL);
try
{
if (pArchive->IsStoring()) {
// Запись имени и идентификатора сотрудника
(*pArchive) << m_strName;
(*pArchive) << m_nId;
}
else {
// Чтение имени и идентификатора сотрудника
(*pArchive) >> m_strName;
(*pArchive) >> m_nId;
}
}
catch (CException* pException)
{
nStatus = ERROR;
}
return (nStatus);
}
Шаг 4 – Освобождение памяти
После завершения сериализации вы должны освободить память, закрыв архив и файл данных.
pArchive->Close();
delete pArchive;
pFile->Close();
delete pFile();
Заключение
Здесь сериализация была описана кратко, в двух словах. В Части 2 описывается, как обрабатывать чтение данных из неисправных хранилищ данных и поддерживать различные версии нашего объекта. В Части 3 рассматривается сериализация сложных объектов.
Автор: Ravi Bhavnani