Вопросы от начинающих MQL5 MT5 MetaTrader 5 - страница 1201

 
Сергей Таболин:

Я пишу всё в один файл. Запись, с последующим чтением, нескольких структур в один файл проходит нормально.

Но читается массив от начала до конца. Как вы его разбиваете на 3 части? Как вы записали структуру и в тот-же файл умудрились записать массив? Я самоучка, много чего не знаю, но то, что это разные форматы данных, как-то подозреваю.

Я допускаю, что можно исхитриться и вот так, открыв файл для записи один раз впихнуть в него три массива, но так просто его частями не прочитаешь.

 
Alexey Viktorov:

Но читается массив от начала до конца. Как вы его разбиваете на 3 части? Как вы записали структуру и в тот-же файл умудрились записать массив? Я самоучка, много чего не знаю, но то, что это разные форматы данных, как-то подозреваю.

Я допускаю, что можно исхитриться и вот так, открыв файл для записи один раз впихнуть в него три массива, но так просто его частями не прочитаешь.

Я же говорю, если в один файл записать только 1 структуру и 3 массива, то потом их оттуда можно прочитать (с условием, что для чтения массивов нужно указать размер каждого из них). Но вот фокус с записью и последующим чтением нескольких таких последовательностей у меня не прокатил. Возможно, нужно двигать указатель, но это уже напряжно...

 
Сергей Таболин:

Я же говорю, если в один файл записать только 1 структуру и 3 массива, то потом их оттуда можно прочитать (с условием, что для чтения массивов нужно указать размер каждого из них). Но вот фокус с записью и последующим чтением нескольких таких последовательностей у меня не прокатил. Возможно, нужно двигать указатель, но это уже напряжно...

Как это напряжно? Лошадиных сил не хватает? А как вы можете быть уверены что запись прошла успешно и как вы это предполагаете, если прочесть не получилось? Насколько мне известно .bin файл глазками не посмотришь.

 
Сергей Таболин:

Артём, можно пример? С учётом, что размер массивов динамический.

Нет, пока примеров не будет - сам ещё не делал, и когда буду делать, буду описывать в статьях. И будет ещё не скоро. Факт в том, что записывать в файл при помощи FileWriteStruct() можно только POD-структуры. Т.е. - простые структуры, не содержащие строки, динамические массивы, виртуальные функции, а также указатели на объекты и функции.

А это значит, что нужно придумывать и тестировать. Но направление я написал. Над реализацией нужно думать.

 
Artyom Trishkin:

Нет, пока примеров не будет - сам ещё не делал, и когда буду делать, буду описывать в статьях. И будет ещё не скоро. Факт в том, что записывать в файл при помощи FileWriteStruct() можно только POD-структуры. Т.е. - простые структуры, не содержащие строки, динамические массивы, виртуальные функции, а также указатели на объекты и функции.

А это значит, что нужно придумывать и тестировать. Но направление я написал. Над реализацией нужно думать.

Выходит что как ни крути, а задача не решаема. Ведь у Сергея в примере внутри три динамических массива. Хоть как выстраивай структуру в структуре, она так и останется с динамическим массивом.

А вот если создать массив структур, то проблема решается записью массива. FileWriteArray(). Это уже проверено и в документации чётко сказано о записи массива структур.

 
Alexey Viktorov:

Но читается массив от начала до конца. Как вы его разбиваете на 3 части? Как вы записали структуру и в тот-же файл умудрились записать массив? Я самоучка, много чего не знаю, но то, что это разные форматы данных, как-то подозреваю.

Я допускаю, что можно исхитриться и вот так, открыв файл для записи один раз впихнуть в него три массива, но так просто его частями не прочитаешь.

в бинарный файл можете писать любые структуры, массивы, даже отдельные переменные - и все в один файл

НО при чтении Вы должны именно в этом же порядке и читать данные

все будет работать

не смотрел дамп файла при записи с помощью FileWriteArray() , скорее всего размер массива в первых байтах будет записан - но проще просто тестовый скрипт составить, там с десяток строк кода ;)

 
Alexey Viktorov:

Выходит что как ни крути, а задача не решаема. Ведь у Сергея в примере внутри три динамических массива. Хоть как выстраивай структуру в структуре, она так и останется с динамическим массивом.

А вот если создать массив структур, то проблема решается записью массива. FileWriteArray(). Это уже проверено и в документации чётко сказано о записи массива структур.

Массив-то структур сохраняется, но.., если бы там были строки, то их можно в массив uchar запаковать внутри структуры, что с успехом делается. А вот массив double в массив uchar никак не влезет. Тем более, что он динамический. А сохранять отдельно три массива в файлы, и потом их пихать в распакованную из файла структуру... Не пробовал. Не думал, не знаю.

 
Igor Makanu:

в бинарный файл можете писать любые структуры, массивы, даже отдельные переменные - и все в один файл

НО при чтении Вы должны именно в этом же порядке и читать данные

все будет работать

не смотрел дамп файла при записи с помощью FileWriteArray() , скорее всего размер массива в первых байтах будет записан - но проще просто тестовый скрипт составить, там с десяток строк кода ;)

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

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

Вопросы от начинающих MQL5 MT5 MetaTrader 5

Сергей Таболин, 2020.03.24 18:02

Спрашиваю ))))

Попробовал сделать "по своему".

Первая структура и 3 массива считываются нормально (при условии, что массивы приёмники не динамические, иначе в первый массив считываются все данные, записанные после структуры).

Однако, если записей больше, то 

   // Проверка
   double   rdata_1[6];
   double   rdata_2[6];
   double   rdata_3[6];
   
   filehandle = FileOpen(filename,FILE_READ|FILE_COMMON|FILE_BIN);
   if(filehandle != INVALID_HANDLE)
   {
      while(!FileIsEnding(filehandle))
      {
         FileReadStruct(filehandle,rfann);
         FileReadArray(filehandle,rdata_1);
         FileReadArray(filehandle,rdata_2);
         FileReadArray(filehandle,rdata_3);
         Print("++++++++++++++++++++++++++++++");
         Print("Структура");
         Print(rfann.v_main_up+"|"+rfann.v_main_dn+"|"+rfann.v_add_up+"|"+rfann.v_add_dn+"|"+rfann.answer);
         Print("Массивы");
         Print("--- 1");
         ArrayPrint(rdata_1);
         Print("--- 2");
         ArrayPrint(rdata_2);
         Print("--- 3");
         ArrayPrint(rdata_3);
      }
   }

выдаёт чёрте чё...

Структура
4.0|-1.0|2.8|-0.7|1
Массивы
--- 1
 1.00000  0.33225 -0.76202 -0.93263 -1.00000 -0.79174
--- 2
-0.14603  0.89562  0.91407  0.93450  0.89481  0.89829
--- 3
 0.89564  0.89217 -0.91174 -0.86623 -1.00000 -0.07680
++++++++++++++++++++++++++++++
Структура
1.839259944929932e+277|-nan|5.295254096666168e-315|3.0|-618173028
Массивы
--- 1
 2.10000 -2.00000 -1.40000 -0.85098 -1.00000 -0.79900
--- 2
-0.30490  0.47926  1.00000  0.70827  0.84163  0.84134
--- 3
 0.83925  0.84173  0.84760  0.84678  0.80368 -0.00063
++++++++++++++++++++++++++++++
Структура
9.384173261527221e-276|5.298850499315376e-315|2.955277867691187e+299|-9.638234784517503e-243|-1705145188
Массивы
--- 1
+0.00000 +0.00000  4.00000  2.80000  0.00000  0.00000
--- 2
 1.00000  0.22097 -0.37383 -0.73115 -0.81752 -1.00000
--- 3
-0.87753  0.46919  0.59706  0.76223  0.82610  0.84312
++++++++++++++++++++++++++++++

Вот я и рассуждаю: как можно из одного файла, неизвестно как записанного прочесть структуру и три массива.

Потому я и сказал, что я самоучка много чего не знаю, но так просто его частями не прочитаешь.

И прекрасно понимаю, что есть варианты в .bin файл дописать всё что угодно, но чтобы прочесть надо знать что в каком порядке записано. И возможно что не средствами mql.

 

А вот этого я не понимаю вообще...

      FileSeek(filehandle,0,FILE_END);
'FILE_END' - cannot convert enum                        282     31
'FILE_END' - improper enumerator cannot be used         282     31

Чё тут не то?

 
Alexey Viktorov:

Вот я и рассуждаю: как можно из одного файла, неизвестно как записанного прочесть структуру и три массива.

вот и я пишу, что это проще проверить, в течении 10 минут.... проверил, не пишет FileWriteArray() размер массива в заголовок или первый байт, значит пишем самостоятельно эти значения

#property copyright "IgorM"
#property link      "https://www.mql5.com/ru/users/igorm"

struct SMystruct
{
   double            d_arr[];
   int               i_arr[];
   uchar             c_arr[];
   int               a;
   double            b;
};

//+------------------------------------------------------------------+
void OnStart()
{
   SMystruct mstruct;
   ArrayResize(mstruct.d_arr,5);    ArrayInitialize(mstruct.d_arr,3.1415926);
   ArrayResize(mstruct.i_arr,3);    ArrayInitialize(mstruct.i_arr,1234567890);
   ArrayResize(mstruct.c_arr,7);    ArrayInitialize(mstruct.c_arr,127);
   mstruct.a = 666;
   mstruct.b = 123.123;
//---  
   if(!SaveMStructToFile("mfile.bin",mstruct)) return;
   SMystruct read_struct;
   if(!LoadMStructInFile("mfile.bin",read_struct)) return;
   Print("1. d_arr");
   ArrayPrint(read_struct.d_arr);
   Print("2. i_arr");
   ArrayPrint(read_struct.i_arr);
   Print("2. c_arr");
   ArrayPrint(read_struct.c_arr);
   printf("mstruct.a = %i , mstruct.b = %f",read_struct.a , read_struct.b);
   
}
//+------------------------------------------------------------------+
bool SaveMStructToFile(const string fname,const SMystruct &data)
{
   int h = FileOpen(fname,FILE_WRITE | FILE_BIN | FILE_COMMON);
   if(h<0) { Print("Write IO Err #",GetLastError()); return(false); }
   FileWriteInteger(h,ArraySize(data.d_arr));   FileWriteArray(h,data.d_arr);
   FileWriteInteger(h,ArraySize(data.i_arr));   FileWriteArray(h,data.i_arr);
   FileWriteInteger(h,ArraySize(data.c_arr));   FileWriteArray(h,data.c_arr);
   FileWriteInteger(h,data.a);
   FileWriteDouble(h,data.b);
   FileClose(h);  
   return(true);
}

bool LoadMStructInFile(const string fname,SMystruct &data)
{
   int h = FileOpen(fname,FILE_READ | FILE_BIN | FILE_COMMON);
   if(h<0) { Print("Write IO Err #",GetLastError()); return(false); } 
   int amount = ArrayResize(data.d_arr,(int)FileReadInteger(h));     FileReadArray(h,data.d_arr,0,amount);
       amount = ArrayResize(data.i_arr,(int)FileReadInteger(h));     FileReadArray(h,data.i_arr,0,amount);
       amount = ArrayResize(data.c_arr,(int)FileReadInteger(h));     FileReadArray(h,data.c_arr,0,amount);
   data.a = FileReadInteger(h);
   data.b = FileReadDouble(h);
   FileClose(h); 
   return(true);
}

2020.03.25 10:18:36.058 tst (EURUSD,H1) 1. d_arr

2020.03.25 10:18:36.058 tst (EURUSD,H1) 3.14159 3.14159 3.14159 3.14159 3.14159

2020.03.25 10:18:36.058 tst (EURUSD,H1) 2. i_arr

2020.03.25 10:18:36.058 tst (EURUSD,H1) 1234567890 1234567890 1234567890

2020.03.25 10:18:36.058 tst (EURUSD,H1) 2. c_arr

2020.03.25 10:18:36.058 tst (EURUSD,H1) 127 127 127 127 127 127 127

2020.03.25 10:18:36.058 tst (EURUSD,H1) mstruct.a = 666 , mstruct.b = 123.123000

т.е. если размеры массива динамические - значит самостоятельно пишем размеры массива при записи и при чтении читаем значение размера массива из файла и устанавливаем размеры массивов структуры

в моем примере 2 структуры - одну инициализировали и записали, вторую прочитали, инициализация из данных файла
Причина обращения: