Сохранение объекта класса в файл

Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий
customer11
38
customer11  

Здравствуйте.

Может кто-нибудь подсказать как сохранить объект класса в файл, и как его потом прочитать. Хочется чтобы программа сохраняла в файл объект. Чтобы не пользоваться отдельными функциями FileWrite, FileWriteString, FileWriteDouble, и аналогичными функциями для чтения.

Есть 2 метода в файле FileBin.mqh, находится в папке Include/Files/FileBin.mqh:

для записи

//+------------------------------------------------------------------+
//| Write data of an instance of the CObject class                   |
//+------------------------------------------------------------------+
bool CFileBin::WriteObject(CObject *object)
  {
//--- check handle & object
   if(m_handle!=INVALID_HANDLE)
      if(CheckPointer(object))
         return(object.Save(m_handle));
//--- failure
   return(false);
  }

для чтения

//+------------------------------------------------------------------+
//| Read data of an instance of the CObject class                    |
//+------------------------------------------------------------------+
bool CFileBin::ReadObject(CObject *object)
  {
//--- check handle & object
   if(m_handle!=INVALID_HANDLE)
      if(CheckPointer(object))
         return(object.Load(m_handle));
//--- failure
   return(false);
  }

У кого есть опыт, можете показать короткий пример сохранения в файл объекта, и затем чтения из файла.

Dmitry Fedoseev
57498
Dmitry Fedoseev  

Видите, используются методы Save() и Load() класса CObject? В CObject они виртуальные. Значит свой класс надо делать потомком CObject и писать в нем  свои  методы Save() и Load().

Если классы простые и их можно заменить структурами, тогда можно использовать функции FileWriteStruct() и FileReadStruct().

customer11
38
customer11  
С простыми классами понятно. Но если объект содержит строковые переменные или динамические массивы, как сохранить такой объект?
Sergey Dzyublik
4529
Sergey Dzyublik  
customer11:
С простыми классами понятно. Но если объект содержит строковые переменные или динамические массивы, как сохранить такой объект?

Вам уже ответили.

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Сохранение объекта класса в файл

Dmitry Fedoseev, 2018.08.28 08:41

Видите, используются методы Save() и Load() класса CObject? В CObject они виртуальные. Значит свой класс надо делать потомком CObject и писать в нем  свои  методы Save() и Load().

Если классы простые и их можно заменить структурами, тогда можно использовать функции FileWriteStruct() и FileReadStruct().


customer11
38
customer11  

Я бы не писал сюда если бы знал как это реализовать. В начале попросил дать, если не сложно, короткий пример сохранения объекта класса в файл. 

class CBase : public CObject
{
   private:
      
      string strValue;
      double dblValue;
      double arrValue[];
      long   lngValue;
      int    intValue;
      
   public:
      
      CBase(void);
     ~CBase(void);
};

Можно ли объект вышеописанного класса сохранить в один файл. Или нужно создавать, как советовалось, метод, в котором по-отдельности сохранять типы string, double, int, отдельно массив.

Vasiliy Sokolov
30990
Vasiliy Sokolov  
customer11:

Я бы не писал сюда если бы знал как это реализовать. В начале попросил дать, если не сложно, короткий пример сохранения объекта класса в файл. 

Можно ли объект вышеописанного класса сохранить в один файл. Или нужно создавать, как советовалось, метод, в котором по-отдельности сохранять типы string, double, int, отдельно массив.

Реализации из коробки нет. Вам необходимо самостоятельно написать весь функционал сохранения класса в файл. Для этого все его поля strValue, dblValue и т.д. нужно сконвертировать в текстовой а лучше в бинарный формат, а затем этот массив сохранить в файл. Имея данные в бинарном формате, можно дополнительно сжать их, используя архиватор Zip, что хорошо скажется на скорости доступа к файлу и его размере.

Vladimir Simakov
6131
Vladimir Simakov  

Структуры, содержащие динамические объекты(динамические массивы, строковые литералы которые в С++ являются такими же динамическими массивами), передавать в файл нельзя, причем это, как я понял не их ограничение, а WinAPI.

Как я сам это обошел:

  1. Стоит задача - передать структуру, содержащую название инструмента.
  2. В структуре объявляем не string symbol, а ushort symbol[10].
  3. Пишем функцию, которая переносит посимвольно литерал в массив кодов unicode, оставшиеся неиспользованными элементы массива инициализируем 0х00.
  4. Пишем обратную функцию.

В результате, получаем структуру без динамического объекта.

В случае с динамическим массивом, выход могу предложить следующий:

  1. Стоит задача передать массив double a[].
  2. Объявляем в структуре массив с заведомо большим количеством элементов, например double a[10000].
  3. Объявляем в структуре переменную int b, в котрую передаем размер массива, который нужно передать, это нужно для того, что бы определить конец передаваемого массива в массиве а[10000] (у нас же значения последних элементов передаваемого массива могут быть равны 0х00).
  4. Далее все по аналогии со строковым литералом.
Viktar Dzemikhau
3386
Viktar Dzemikhau  
Vladimir Simakov:

Структуры, содержащие динамические объекты(динамические массивы, строковые литералы которые в С++ являются такими же динамическими массивами), передавать в файл нельзя, причем это, как я понял не их ограничение, а WinAPI.

Как я сам это обошел:

  1. Стоит задача - передать структуру, содержащую название инструмента.
  2. В структуре объявляем не string symbol, а ushort symbol[10].
  3. Пишем функцию, которая переносит посимвольно литерал в массив кодов unicode, оставшиеся неиспользованными элементы массива инициализируем 0х00.
  4. Пишем обратную функцию.

В результате, получаем структуру без динамического объекта.

В случае с динамическим массивом, выход могу предложить следующий:

  1. Стоит задача передать массив double a[].
  2. Объявляем в структуре массив с заведомо большим количеством элементов, например double a[10000].
  3. Объявляем в структуре переменную int b, в котрую передаем размер массива, который нужно передать, это нужно для того, что бы определить конец передаваемого массива в массиве а[10000] (у нас же значения последних элементов передаваемого массива могут быть равны 0х00).
  4. Далее все по аналогии со строковым литералом.

Ого. Это какой-то головняк, хотя.. я понимаю о чём Вы говорите, но..

Я бы предложил топикстатрету осилить работу с СУБД, например, sqlite3. Да, неделю можно выкинуть из жизни по непривычке, но.. Преимущество очевидно. Скорость записи в базу данных в разы быстрее и как-бы это сказать, комфортнее. Я это сделал, когда увидел некоторе моменты при работе с нативной мкл функцией записи в файл, есть там с передачей ключа или как его назвать костыль. Я продолбался несколько часов. Потом всё-таки костыль был определён. Но мне это не понравилось. Привычки писать так, как нравится, и не забивать мозг дополнительныцми костылями. Хотя, нативные средства тоже работают, но мне они не понравились как-то.

Хотя, теритически не важно на чёи писать, если скорость не важно. Либой объект это набор полей разного типа и не более того. Пишешь каждое поле отдельно и всё..

Andrei Novichkov
8232
Andrei Novichkov  
Какое то время тому назад здесь проскакивала библиотека как раз по сохранению объектов в файл в формате JSON. И чтение объектов из файла. Кажется это был аналог Rapidjson для MQL.
Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий