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

 
Yedelkin:

Вопрос 1: Вы считаете, что в документации опечатка, и что вместо "Дата последнего чтения" должно стоять что-то типа "Дата последнего открытия"?

Да, вот дословно:

lpLastAccessTime [out, optional]

A pointer to a FILETIME structure to receive the date and time the file or directory was last accessed. The last access time includes the last time the file or directory was written to, read from, or, in the case of executable files, run.

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

С перезакрытием хэндла я наверное неправ, но есть еще такой интересный текст:

Not all file systems can record creation and last access times and not all file systems record them in the same manner. For example, on FAT, create time has a resolution of 10 milliseconds, write time has a resolution of 2 seconds, and access time has a resolution of 1 day (really, the access date). Therefore, the GetFileTime function may not return the same file time information set using the SetFileTime function.

NTFS delays updates to the last access time for a file by up to one hour after the last access. NTFS also permits last access time updates to be disabled. Last access time is not updated on NTFS volumes by default.

В текущей ситуации щастье ожидается, когда свойства файлов будут получены без "переоткрытия" хендла.

Видимо, щастя таки не будет, по крайней мере в случае когда речь идет о секундах.
 
TheXpert:

Да, вот дословно:

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

С перезакрытием хэндла я наверное неправ, но есть еще такой интересный текст:

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

Спс за расширение кругозора! М-дя... Облом-с.

Вот этот скрипт говорит о том, что вместо "Даты последнего чтения" идентификатор FILE_ACCESS_DATE вообще возвращает время предыдущего закрытия файла:

int handle_file;
void OnStart()
  {
   Print("===============================================");
   handle_file=FileOpen("Ye_file2.bin",FILE_READ|FILE_WRITE|FILE_BIN);
   switch(handle_file)
     {
      case  INVALID_HANDLE: break;
      default:
         Print("Дата создания файла Ye_file2.bin: ",(datetime)FileGetInteger(handle_file,FILE_CREATE_DATE));
         for(int i=0;i<3;i++)
           {
            Sleep(2000);
            FileReadInteger(handle_file,CHAR_VALUE);
            Print("Дата последнего чтения Ye_file2.bin: ",(datetime)FileGetInteger(handle_file,FILE_ACCESS_DATE));
           }
         Sleep(3000);
         Print("Время обращения к FileClose(handle_file): ",TimeTradeServer());
         FileClose(handle_file);
     }
  }
 
TheXpert:

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

Кстати, за три прошедших месяца комментариев так и не дождался, поэтому пока избегаю применять функцию FileFlush().
 

Мне кажется FileFlush не должна замедлять/ускорять работу программы, если ее использовать вместо FileClose. 

Просто не имеет смысла ее использовать в цикле при каждой записи. Представьте как тормозилась бы работа Word`а если бы он после каждого изменения документа производил бы пересохранеение (особенно если  этот документ имеет кучу текста и картинок). FileFLush лишь облегчает сохранение без закрытия фаилов.

Наверное разработчики подразумевали так(К примеру):

 OnInit - FileOpen 

On Tick - FileWrite FileFlush

  (и тут данные сохраняются -FileFlash - в цикле не каждый проход цикла, а после завершения цикла)

OnDeinit FileClose. 

 

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

......наверное) 

 
Yedelkin:
Кстати, за три прошедших месяца комментариев так и не дождался, поэтому пока избегаю применять функцию FileFlush().
Она все равно не гарантирует сохранения сразу. Так что смысл есть ее применять только для сохранения текущего состояния без закрытия хендла.
 
Yedelkin:
Кстати, за три прошедших месяца комментариев так и не дождался, поэтому пока избегаю применять функцию FileFlush().

Для лучшего понимания смысла в использовании функции FileFlush() нужно задуматься о понятии буфера ввода/вывода файла... Как известно на диске информация храниться в байтах и записывание каждого байта по отдельности (по мере их поступления) есть верхом расточительства! Если смотреть на этот процесс с "железячной" стороны, то операционной системе придется, при каждом запросе на операцию записывания байта, "мотать записывающей бошкой" привода жесткого диска! А ведь жесткий диск это кинематика! Иными словами самое медленное из устройств компьютера. Так какой же тогда выход? А очень простой! В памяти компьютера создается буфер данных (обычно это несколько десятков килобайт) в который посылаются данные из функции FileWrite и ей же подобных, как только данный буфер будет полностью заполнен система его целиком записывает на жесткий диск в виде непрерывного блока данных, при этом не производится излишние манипуляции головкой привода, а просто данные записываются ОДНИМ МАХОМ! Теперь посчитайте во сколько раз увеличивается скорость записи 32 килобайт информации за раз по сравнению с записью каждого байта по отдельности такого же объема ;) А посчитать довольно просто... Для каждой операции записи сначала позиционируется головка привода, потом производится запись. И это еще не вдаваясь во все "тяжкие" работы винчестера при чтении/записи :) В случае же буфера мы один раз позиционируем головку и записываем весь блок одним потоком!

Но все это говорит о том, что до тех пор пока ваш буфер не будет заполнен, ваши данные в файле физически не появятся (!!!), либо пока вы не закроете сам файл, в этом случае буфер (вернее  то, что в нем осталось)  записывается на диск сразу. Вот тут-то и приходит на помощь функция FileFlush. Когда вы "записали" в файл какую то информацию и вам необходимо ее гарантированное физическое появление в файле (к примеру эта информация может уже быть востребована другой программой, индикатором, советником...), то вы можете вызвать функцию FileFlush которая физически сбросит содержимое буфера на винт (в файл)!

Вывод: Частое использование функции FileFlush либо использование ее  в циклах, для ускорения работы с файлом, даст прямо противоположный результат, так как при каждом ее вызове системе необходимо вычислить реально содержащееся в буфере ввода/вывода количество информации, вызвать операционную систему и дать команду на запись данного участка памяти в файл! К примеру в цикле производится запись в файл одного байта и сразу вызывается функция FileFlush, получаем самый медленный способ записи на диска ПОБАЙТОВО!!! ;)

Так как же наиболее быстро писать в файл? Да очень просто ;) Не морочить голову и не мучить FileFlush :) В этом случае вы получаете быстрый обмен данными между FileWrite и буфером обмена (манипуляции в памяти самые быстрые), а система уже сама будет следить за переполнением этого буфера и при необходимости производить потоковую запись данных (максимально быстрая операция с таким неповоротливым устройством как винчестер!) и очистку буфера для приема новых данных!!!

Тогда возникает вопрос - "А на кой нужна функция FileFlush???". А ответ прост - она нужна когда необходимо что бы данные были физически записаны в файл в не зависимости от наполнения буфера. Пример такой необходимости приводил выше.

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

Пришлось переписать свой индикатор под MQL5 и столкнулся с серьезной непоняткой :(

Вот код:

  first_bar=ChartGetInteger(0,CHART_FIRST_VISIBLE_BAR,0);
  
  //--- установим доступ к массиву как к таймсерии
  ResetLastError();
  int copied=CopyTime(NULL,0,0,first_bar,TimeAsSeries);
  del();
  int handle=FileOpen("Price Label\\"+_Symbol+tpl_ext,FILE_READ|FILE_CSV,';',CP_ACP);
  int er=GetLastError();
  ResetLastError();
  
  string sTF="";
  int TF;
  string period_name;
  string price_label;
  string price1;
  string price2;
  
  if (handle>=1){
    while(FileIsEnding(handle)==false){
      sTF = FileReadString(handle);
      TF = ResolveTF(sTF);
      period_name=FileReadString(handle);
      price_label=FileReadString(handle);
      price1=FileReadString(handle);
      price2=FileReadString(handle);
      drawe_price(TF,handle,period_name,price_label,price1,price2);
    }
    FileClose(handle);
  }
  return(0);

Сразу поясню, что такое количество переменных введено для того, что бы увидеть в дебагере что происходит. И увидел...

В файле записано куча строк, в каждой строке 5 секций разделенных ";". Первый же вызов 

sTF = FileReadString(handle);

загоняет в переменную sTF весь файл целиком, причем в непонятной кодировке. Судя по тому, что я вижу в дебагере (в переменной sTF краказёбы типа китайских иероглифов) он прочитал содержимое файла как уникод! При открытии файла перепробывал все допустимые кодовые страницы, но результат тот же :( Сам файл записан в виндовой кодировке.

Кто нибудь имеет представление где тут собака порылась?

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

is_vale

Спасибо всем, поделившимся информацией! Буду заново погружаться в тему.

 
FILE_ANSI
 
is_vale:

Кто нибудь имеет представление где тут собака порылась?

Давно с файловыми операциями не работал.. Посмотрите, у Вас при использовании FileOpen() объявлен файл типа CSV. Раньше указывалось, что все записанные элементы преобразуются к строкам unicode или ansi. Может, здесь собака?