Чтение бинарных файлов из индикатора

 
if (!ChartScreenShot(0, name, screenWidth, screenHeight, ALIGN_RIGHT))
      return (false);

   ResetLastError();
   if(!FileIsExist(name,false))
      return (false);

   //---
   int flags=FILE_READ|FILE_BIN;

   //---
   int file=FileOpen(name,flags);
   if(file==INVALID_HANDLE)
      return(false);

   uchar photo[];
   FileReadArray(file,photo);
   FileClose(file);

Вот фрагмент кода, делается скрин экрана и читается картинка из файла. В советнике работает на ура, в индикаторе возвращается пустой массив. Есть какие то ограничения по работе с файлами в индикаторах?? В докумениации никаких ограничений не нашел

 
Самое интересное здесь - как вы пришли к такому выводу? А код - не весь, и сделать какой-то вывод исходя из него - нельзя.
 
Dmitry Fedoseev:
Самое интересное здесь - как вы пришли к такому выводу? А код - не весь, и сделать какой-то вывод исходя из него - нельзя.
//+------------------------------------------------------------------+
//|                                                         Test.mq5 |
//|                        Copyright 2019, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2019, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_chart_window
#property indicator_plots   1
#property indicator_buffers 1

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
TestPhoto();
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//---
   
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+

void TestPhoto() {
   string name;
   MqlDateTime  dtLocal;
   TimeToStruct(TimeLocal(), dtLocal);
   string date = IntegerToString(dtLocal.year) + IntegerToString(dtLocal.mon, 2, '0') + IntegerToString(dtLocal.day, 2, '0');
   string time = IntegerToString(dtLocal.hour, 2, '0') + "." + IntegerToString(dtLocal.min, 2, '0') + "." + IntegerToString(dtLocal.sec, 2, '0');
   name = "ScreenShots/" + date + "/" + _Symbol + "_" +date + "_" + time + ".png";
   
if (!ChartScreenShot(0, name, 800, 600, ALIGN_RIGHT))
      return;

   ResetLastError();
   if(!FileIsExist(name,false))
      return;
  
   //---
   int flags=FILE_READ|FILE_BIN|FILE_SHARE_READ;

   //---
   int file=FileOpen(name,flags);
   if(file<0) {
      Print("Операция FileOpen неудачна, ошибка ",GetLastError());
      return;
}
   uchar photo[];
   FileReadArray(file,photo);
   FileClose(file);
   
   Print(ArraySize(photo));
}
 

Оказывается, дело не в чтении файла, а в сохранении скриншота функцией ChartScreenShot(). Получается, что функция асинхронно работает. Сразу после вызова скриншот еще не успел сохраниться, файл есть, но он пустой. И это, скорее всего, не баг, а фича - чтобы индикаторы не тормозили. 

Если надо во что бы то ни стало, то после вызова ChartScreenShot() можно добавить какой-нибудь цикл, что бы паузу обеспечить, или в цикле проверять, пока в файле что-то не появится. 

 
for (int i=0; i < 100000; i++){
      if (FileIsExist(name,false) && FileSize(name) > 0)
         break;
   }

Добавил такой код, ничего не изменилось, файл создается, но не читается

Пробовал также Sleep в цикле, ничего не меняется

 

А я вот так делал: 

   for(int i=0;i<10;i++) 
   ChartRedraw();

Гарантии нет.

Можно так: в TestPhoto() делать только сохранение скриншота и сохранять его имя в строковый массив. Где-то в другом месте, может, в OnTimer() или в OnCalculate() проверять, появилось ли что-то в файле и сдвигать массив, что-то делать с файлом.

 

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

 

Вам доки для чего?

...

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

...

А вот к разрабам опять вопрос. Эта инфа есть в справке к mql4, а в mql5 уже не упоминается.
 
Vladimir Simakov:

Вам доки для чего?


...

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

...

по моему там еще что то мешает

вот набросал код индикатора - пишем каждые 10 секунд:

#property copyright "IgorM"
#property link      "https://www.mql5.com/ru/users/igorm"
#property version   "1.00"
#property indicator_chart_window
#property indicator_plots 0
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
{
   EventSetTimer(10);

//---
   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   EventKillTimer();

}
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
{
//---

//--- return value of prev_calculated for next call
   return(rates_total);
}
//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
{
   ResetLastError();
   if(!SaveScreenShot()) Print("Ошибка сохранения скриншота № ",GetLastError());
   else Print("Сохранил скриншот");

}
//+------------------------------------------------------------------+
bool SaveScreenShot()
{
   MqlDateTime  dtLocal;
   TimeLocal(dtLocal);
   string date = IntegerToString(dtLocal.year) + IntegerToString(dtLocal.mon, 2, '0') + IntegerToString(dtLocal.day, 2, '0');
   string time = IntegerToString(dtLocal.hour, 2, '0') + "." + IntegerToString(dtLocal.min, 2, '0') + "." + IntegerToString(dtLocal.sec, 2, '0');
   string fname = "ScreenShots/" + date + "/" + _Symbol + "_" + date + "_" + time + ".png";
   if (!ChartScreenShot(0, fname, 800, 600, ALIGN_RIGHT)) return(false);
   return(true);
}
//+------------------------------------------------------------------+

в теории все работает - вижу папку MQL5\Files\ScreenShots\20191207 в ней появляются файлы

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

 
Vladimir Simakov:

Вам доки для чего?

...

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

...

А вот к разрабам опять вопрос. Эта инфа есть в справке к mql4, а в mql5 уже не упоминается.

А какая польза от столь ценной информации? И так понятно, что не сразу все происходит.

 
Igor Makanu:

по моему там еще что то мешает

вот набросал код индикатора - пишем каждые 10 секунд:

в теории все работает - вижу папку MQL5\Files\ScreenShots\20191207 в ней появляются файлы

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

Неуж-то разрабы забыли handle закрыть? Так, мысли вслух.