Работа с файлами. - страница 3

 
Yedelkin:
"При закрытии файла данные сбрасываются на диск автоматически, поэтому нет необходимости вызывать функцию FileFlush() перед вызовом функции FileClose()" - Да-да, начинаю понимать, о чём говорил sergeev. Получается, что для гарантированного сохранения последней записи в файл можно вместо FileClose() вызывать FileFlush()? И это будет грамотным решением?

не вместо, а по необходимости.

Flush - сбрасывает остатки данных, и НЕ закрывает файл. Вы ведь это хотите?

Close- сбрасывает остатки данных на диск и закрывает.

 
sergeev:

не вместо, а по необходимости.

Flush - сбрасывает остатки данных, и НЕ закрывает  файл. Вы ведь это хотите?

Close- сбрасывает остатки данных на диск и закрывает.

Да, именно об этом речь. Спасибо за подсказку о грамотном решении!
 
Yedelkin:

Что-то минимизация по времени с использованием  FileFlush() не очень получается:

2011.05.29 21:58:20 FlushSave (EURGBP,M1) FileFlush. GetTickCount() = 133766
2011.05.29 22:00:33 FlushSave (EURGBP,M1) FileClose. GetTickCount() = 133734
Фактически, на работу обеих функций уходит одинаковое время.

Как я понял вот эта строка перемещает позицию в начало файла без смещения. Что позволяет затереть имеющуюся инфу (т.е. дата обновляется но при этом не накапливается в файле)

FileSeek(handle_file,0,SEEK_SET);

При этом если использовать вместо SEEK_SET переход в конец файла данные накапливаются в файле.

 
Yedelkin:

Вы при Flush каждый раз открываете новый хэндл файла. Зачем? И не закрываете кстати.

Плюс функции FileFlush именно в том, что не надо переоткрывать хэндл.

Документация по MQL5: Файловые операции / FileFlush
Документация по MQL5: Файловые операции / FileFlush
  • www.mql5.com
Файловые операции / FileFlush - Документация по MQL5
 
Interesting:

1. Как я понял вот эта строка перемещает позицию в файле без смещения. Что позволяет затереть имеющуюся инфу (т.е. дата обновляется но при этом не накапливается в файле)

При этом если использовать вместо SEEK_SET переход в конец файла данные накапливаются в файле.
Уже успел удалить своё сообщение. Там в примере вставлял FileFlush() после записи в файл.
 
TheXpert:

Вы при Flush каждый раз открываете новый хэндл файла. Зачем? И не закрываете кстати.

Плюс функции FileFlush именно в том, что не надо переоткрывать хэндл.

 

Сделал вот так:

int handle_file;
datetime t;
uint u;
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//---пример с функцией FileFlush()
   u=GetTickCount();
   handle_file=FileOpen("Ye_file.txt",FILE_READ|FILE_WRITE|FILE_TXT);
//for(int i=0;i<100000;i++)
   for(int i=0;i<1000;i++)
     {
      if(handle_file!=INVALID_HANDLE)
        {
         t=TimeLocal();
         FileSeek(handle_file,0,SEEK_SET);
         FileFlush(handle_file);
         FileWrite(handle_file,t);
        }
     }
   FileClose(handle_file);
   Print("FileFlush. GetTickCount() = ",GetTickCount()-u);

//---пример без функции FileFlush()
   u=GetTickCount();
   for(int i=0;i<1000;i++)
     {
      handle_file=FileOpen("Ye_file.txt",FILE_READ|FILE_WRITE|FILE_TXT);
      if(handle_file!=INVALID_HANDLE)
        {
         t=TimeLocal();
         FileSeek(handle_file,0,SEEK_SET);
         FileWrite(handle_file,t);
         FileClose(handle_file);
        }
     }
   Print("FileClose. GetTickCount() = ",GetTickCount()-u);
  }

Результат:

2011.05.29 23:14:31 FlushSave (EURGBP,M1) FileFlush. GetTickCount() = 13563
2011.05.29 23:14:32 FlushSave (EURGBP,M1) FileClose. GetTickCount() = 531

При этом поменял местами строчки, согласно документации:

         FileFlush(handle_file);
         FileWrite(handle_file,t);
Но смысла вызывать FileFlush() перед FileWrite() пока  не понял.
 
 
Yedelkin:

Сделал вот так:

Результат:

2011.05.29 23:14:31 FlushSave (EURGBP,M1) FileFlush. GetTickCount() = 13563
2011.05.29 23:14:32 FlushSave (EURGBP,M1) FileClose. GetTickCount() = 531

При этом поменял местами строчки, согласно документации:

Но смысла вызывать FileFlush() перед FileWrite() пока  не понял.
 

Вот такой вариант:

int handle_file;
datetime t;
uint u;

void OnStart()
{
//---пример с функцией FileFlush()
u=GetTickCount();

handle_file=FileOpen("Ye_file.txt",FILE_READ|FILE_WRITE|FILE_TXT);

  for(int i=0;i<1000;i++)
  {
    if(handle_file!=INVALID_HANDLE)
    {
    t=TimeLocal();
    FileSeek(handle_file,0,SEEK_END);
    FileFlush(handle_file);
    FileWrite(handle_file,t);
    }
  }

FileClose(handle_file);

Print("FileFlush. GetTickCount() = ",GetTickCount()-u);

}

Результат - FileFlush. GetTickCount() = 26125

Вот такой вариант:

int handle_file;
datetime t;
uint u;

void OnStart()
{
//---пример без функции FileFlush()
u=GetTickCount();

  for(int i=0;i<1000;i++)
  {
  handle_file=FileOpen("Ye_file2.txt",FILE_READ|FILE_WRITE|FILE_TXT);
      
    if(handle_file!=INVALID_HANDLE)
    {
    t=TimeLocal();
    FileSeek(handle_file,0,SEEK_END);
    FileWrite(handle_file,t);
    FileClose(handle_file);
    }

  }

Print("FileClose. GetTickCount() = ",GetTickCount()-u);

}
Результат - FileClose. GetTickCount() = 3969
 

Вот такой вариант дал результат от 47 до 110

int handle_file;
datetime t;
uint u;

void OnStart()
{

u=GetTickCount();

handle_file=FileOpen("Ye_file.txt",FILE_READ|FILE_WRITE|FILE_TXT);

  for(int i=0;i<1000;i++)
  {
    if(handle_file!=INVALID_HANDLE)
    {
    t=TimeLocal();
    FileSeek(handle_file,0,SEEK_END);
    FileWrite(handle_file,t);
    }
  }

FileClose(handle_file);

Print("FileFlush. GetTickCount() = ",GetTickCount()-u);

}

1. Вывод - Использование FileFlush в цикле замедляет выполнение примерно в 260 раз.

2. Цикл на 50000 записей в таком варианте имеет следующий результат - FileFlush. GetTickCount() = 1891

3. При выполнении цикла на 50000 записей мне так и не удалось вырубить терминал без завершения записи в файл (закрывал терминал и "убивал" процесс).

4. При цикле в 100000 записей удавалось убить терминал, при этом в файле было больше 65536 записей (стока помещается в Excel 2003).

 
Yedelkin:

При этом поменял местами строчки, согласно документации:

Где в документации такое написано?

Но смысла вызывать FileFlush() перед FileWrite() пока  не понял.

Как можно понять смысл того, в чем его нет? Верните порядок строк на родину и перепроверьте. Видимо в документации не совсем правильно выразились.

Но... Благодаря вашим тестам таки ошибка видимо обнаружилась -- FileFlush видимо жрет непозволительно много времени при отсутствии изменений.

Interesting:

ОМГ! Там где вывод вообще маразм. Вот так потом и появляются заявочки типа "ООП быстрее" или "индикаторы медленные, надо переносить весь код в советник" .

 
papaklass:

Эксперт, напишите как правильно пользоваться этой функцией.

Гипотетически так:

// open handle
for(int i=0;i<1000;i++)
  {
    if(handle_file!=INVALID_HANDLE)
    {
    t=TimeLocal();
    FileSeek(handle_file,0,SEEK_END);
    FileWrite(handle_file,t);
    FileFlush(handle_file);
    }
  }
// close handle

Т.е. корректно сравнивать связку FileClose -- FileOpen с FileFlush.

Теоретически FileFlush должен быть составной частью FileClose и никак не может быть медленней связки. 

Смысла флашить изменения до их появления нет, т.к. их еще нет :)

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

Причина обращения: