Русский

Учебник по MQL4  Стандартные функции  Файловые операции

Файловые операции


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

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

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

Имена и каталоги файлов


Название рабочего файла должно быть составлено в соответствии с правилами операционной системы. Название любого файла, используемого в MQL4, состоит из двух частей - имени файла и его расширения, разделённых точкой, например, News.txt. Технически название файла никак не связано с содержащейся в нём информацией, поэтому и имя файла и его расширение могут быть заданы программистом произвольно. Имя файла обычно выбирается таким, чтобы оно отражало суть содержащихся в нём данных.

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

Наиболее распространёнными типами файлов (тип определяется расширением) являются следующие:

- .txt - текстовый файл, для просмотра используется блокнот, Word, FrontPage и др. редакторы;

- .csv - файл для построения таблиц в Excel;

- .htm - файл для просмотра в браузере, например, Internet Explorer, Netscape Navigator и др.

Существует три каталога (с подкаталогами), в которых могут располагаться рабочие файлы:

- Каталог_терминала\Experts \History\<текущий брокер>\ - для файлов истории;

- Каталог_терминала\Experts \Files\ - для общего случая;

- Каталог_терминала\Tester\ Files\ - для файлов, используемых при тестировании.

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

Режимы работы файлов


Технология взаимодействия прикладной программы с рабочим файлом предусматривает несколько возможных режимов. В общем случае один файл может быть открыт одновременно несколькими программами (в пределах одного компьютера или в нескольких компьютерах, соединённых в сеть). При этом операционная среда обеспечивает лишь для одной из таких программ полный доступ к файлу, а именно, возможность чтения и записи в файл, а для всех остальных программ - доступ только для чтения. Например, если файл My_text. doc уже открыт какой-то программой для чтения и записи, то все другие программы перед открытием файла получат уведомление:


Рис. 146. Диалоговое окно, возникающее при попытке доступа к файлу, открытому другой программой.

Использование указанной технологии гарантирует, что один файл не будет изменяться одновременно двумя различными программами. Для того, чтобы исполняемая прикладная программа могла взаимодействовать с рабочим файлом, его прежде всего необходимо открыть. Режим открытия файла указывается в функции FileOpen().

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

Файловый описатель – уникальный номер файла, открытого исполняемой программой в текущий момент.

При успешном открытии файла функция FileOpen () возвращает некоторое целое значение (обычно это значение присваивается переменной handle), которое и является файловым описателем. Большинство функций, предназначенных для работы с файлами, предполагают использование значения файлового описателя в качестве одного из формальных параметров.

Функция FileOpen()

 int FileOpen(string filename, int mode, int delimiter=';')

Функция открывает файл для ввода и/или вывода. Функция возвращает файловый описатель открытого файла или -1 в случае неудачи. Файлы могут открываться только в каталоге Каталог_терминала\Experts \Files\ или в каталоге Каталог_терминала\Tester\Files\ (в случае тестирования эксперта) или в их подкаталогах.

Параметры:

filename - название файла;

mode - способ открытия файла; принимает значения (или их комбинацию): FILE_BIN, FILE_CSV, FILE_READ, FILE_WRITE;

delimiter - знак разделителя для csv-файлов. По умолчанию применяется символ ';'.

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

Режим открытия файла FILE_WRITE предусматривает, что файл будет использоваться программой только для записи. Попытка открытия файла в этом режиме приводит к открытию файла нулевой длины. Даже если до открытия в файле были данные, то они будут уничтожены. Открытие файла в этом режиме может закончиться неудачей, если файл ранее был открыт другой программой (в режиме записи).

Допускается открытие файла в режиме FILE_READ|FILE_WRITE. Этот режим предусматривает возможность чтения из файла и записи в файл. Режим используется при необходимости дописать данные в файл, уже содержащий какие-то данные. Функция предусматривает обязательное использование одного из режимов FILE_READ или FILE_WRITE или их комбинацию.

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

Функция предусматривает обязательное комбинирование режимов FILE_READ, FILE_WRITE или FILE_READ|FILE_WRITE с режимами FILE_BIN или FILE_CSV. Например, для чтения текстового файла необходимо использовать комбинацию режимов FILE_CSV|FILE_READ, а для того, чтобы добавить запись в бинарный файл, нужно использовать комбинацию FILE_BIN|FILE_READ|FILE_WRITE.

В пределах одного исполняемого модуля (прикладной программы, например, эксперта) одновременно может быть открыто не более 32 файлов. Описатели файлов, открытых в одном модуле, нельзя передавать в другие модули (библиотеки).

Содержание записей в файлах


При любой комбинации режимов записи данных заносятся в файл без промежутков. При формировании файлов в режиме FILE_BIN записи данных заносятся подряд. В зависимости от типа данных, записываемых в файл (и используемых для этого функций записи), между группами записей может прописываться комбинация символов конца строки ("\r\n"). При формировании файлов в режиме FILE_CSV записи данных отделяются файловым разделителем (обычно ';'), а группы записей (составляющих строки) разделяются с помощью комбинации символов конца строки ("\r\n").

Файловый разделитель - специальный символ; запись, которая заносится в файл для разделения записей данных.

Файловый разделитель используется для разделения записей данных только в csv-файлах.

Общий принцип построения записей в любых файлах состоит в том, что записи заносятся в фай в определённой последовательности, без промежутков. Собственно вся запись представляет собой сплошную последовательность символов. Любой файл может быть прочитан какой-либо программой, и (в зависимости от правил, реализованных в этой программе) отображён на экране в том или ином виде. Например, пусть имеется файл File_1.csv со следующим содержанием:

int FileOpen(string filename, int mode, int delimiter=';')

Файл File_1.csv будет по-разному отображён в различных текстовых редакторах:


Рис. 147. Отображение файла File_1 разными программами (File_1.csv).

В данном случае комбинация символов "\r\n" была воспринята каждой из программ (Excel и Блокнот) как указание на порядок форматирования: последовательность данных после комбинации "\r\n" отображается в новой строке, а само сочетание символов "\r\n" в окне редактирования не отображается. В то же время, Excel - табличный редактор, поэтому символ ";" был воспринят этой программой, как разделитель данных на столбцы. Обратите внимание, символ ";" в окне Excel не отображается. Блокнот - текстовый редактор. Правила, реализованные в этой программе, не предполагают деление на столбцы, поэтому символ ";" был воспринят не как файловый разделитель, а как составная часть данных, и поэтому отображён на экране.

Указанные символы (";" и "\r\n") используются для разделения записей в MQL4.


Рис. 148. Разновидности записей в рабочих файлах.

На Рис. 148 представлена структура записей данных в нескольких файлах. В верхней строке показано содержание csv-файла, а в трёх нижних - структуры бинарных файлов. Все эти файлы составлены в соответствии с правилами, соответствующими той или иной функции записи в файл.

Запись в csv-файле - это последовательность строковых значений (типа string), между которыми указываются либо файловый разделитель, либо признак конца строки. И то и другое воспринимается при чтении данных (стандартной функцией MQL4 для чтения файлов) как признак окончания содержательной части считываемого значения. Строковое значение может быть разной длины, и заранее неизвестно, сколько именно символов необходимо прочесть, поэтому считывание выполняется до момента обнаружения программой одного из разделителей.

Записи в двух видах бинарных файлов представляют последовательность данных без каких-либо разделителей. Такой порядок записи определяется фиксированной длиной для данных разного типа: 4 байта для данных типа int, bool, datetime и color и 8 байт (или 4 байта, в зависимости от параметров функции записи) для данных типа double. В этом случае нет необходимости в разделителях, т.к. считывание выполняется с помощью стандартной функции для чтения данных определённого типа фиксированной длины. Последний (нижний на Рис. 148) бинарный файл содержит данные типа string, разделённые признаком конца строки.

Файловый указатель - место в файле, с которого начинается чтение следующего значения.

Понятие "файловый указатель" является аналогом понятия "курсор". Файловый указатель характеризуется позицией в файле. По мере прочтения данных файловый указатель смещается вправо на одну или несколько позиций.

Задача 36. Прочесть из текстового файла данные о важных новостях и отобразить на ценовом графике графические объекты (вертикальные линии) в соответствии со временем публикации новостей.

Пусть в каталоге Каталог_терминала\Experts \Files\ имеется рабочий файл News.csv со следующей записью:


Рис. 149. Содержание рабочего файла News.csv.

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

Решение задачи состоит из двух частей. Сначала необходимо прочесть данные из рабочего файла, а затем полученные значения использовать в качестве координат графических объектов. Чтение данных из текстового файла осуществляется с помощью функции FileReadString().

Функция FileReadString()

 string FileReadString(int handle, int length=0)

Функция читает строку с текущей позиции файла. Применяется как к CSV, так и к двоичным файлам. Для текстовых файлов строка будет прочитана до разделителя. Для бинарных файлов в строке будет прочитано указанное количество символов. Чтобы получить информацию об ошибке, необходимо вызвать функцию GetLastError().

Параметры:

handle - файловый описатель, возвращаемый функцией FileOpen();

length - количество символов для чтения.

Необходимость обработки данных о новостях обычно возникает один раз в начале торгов, поэтому в данном случае, для решения Задачи 36, можно использовать скрипт. Скрипт timetablenews.mq4 предназначен для считывания данных из файла и отображения графических объектов в окне финансового инструмента.

//--------------------------------------------------------------------
// timetablenews.mq4
// Предназначен для использования в качестве примера в учебнике MQL4.
//--------------------------------------------------------------- 1 --
int start() // Спец. функция start
{
//--------------------------------------------------------------- 2 --
int Handle, // Файловый описатель
Stl; // Стиль вертикальной линии
string File_Name="News.csv", // Имя файла
Obj_Name, // Имя объекта
Instr, // Название валюты
One,Two, // 1я и 2я чать названия инстр.
Text, // Текст описания события
Str_DtTm; // Дата и время события(строка)
datetime Dat_DtTm; // Дата и время события(дата)
color Col; // Цвет вертикальной линии
//--------------------------------------------------------------- 3 --
Handle=FileOpen(File_Name,FILE_CSV|FILE_READ,";");// Открытие файла
if(Handle<0) // Неудача при открытии файла
{
if(GetLastError()==4103) // Если файла не существует,..
Alert("Нет файла с именем ",File_Name);//.. извещаем трейдера
else // При любой другой ошибке..
Alert("Ошибка при открытии файла ",File_Name);//..такое сообщ
PlaySound("Bzrrr.wav"); // Звуковое сопровождение
return; // Выход из start()
}
//--------------------------------------------------------------- 4 --
while(FileIsEnding(Handle)==false) // До тех пор, пока файловый ..
{ // ..указатель не в конце файла
//--------------------------------------------------------- 5 --
Str_DtTm =FileReadString(Handle);// Дата и время события(дата)
Text =FileReadString(Handle);// Текст описания события
if(FileIsEnding(Handle)==true) // Файловый указатель в конце
break; // Выход из чтения и рисования
//--------------------------------------------------------- 6 --
Dat_DtTm =StrToTime(Str_DtTm); // Преобразование типа данных
Instr =StringSubstr(Text,0,3);// Извлекаем первые 3 символа
One=StringSubstr(Symbol(),0,3);// Извлекаем первые 3 символа
Two=StringSubstr(Symbol(),3,3);// Извлекаем вторые 3 символа
Stl=STYLE_DOT; // Для всех - стиль пунктир
Col=DarkOrange; // Для всех - цвет такой
if(Instr==One || Instr==Two) // А для событий по нашему ..
{ // .. финансовому инструменту..
Stl=STYLE_SOLID; // .. такой стиль..
Col=Red; // .. и такой цвет верт. линии
}
//--------------------------------------------------------- 7 --
Obj_Name="News_Line "+Str_DtTm; // Имя объекта
ObjectCreate(Obj_Name,OBJ_VLINE,0,Dat_DtTm,0);//Создаем объект..
ObjectSet(Obj_Name,OBJPROP_COLOR, Col); // ..и его цвет,..
ObjectSet(Obj_Name,OBJPROP_STYLE, Stl); // ..стиль..
ObjectSetText(Obj_Name,Text,10); // ..и описание
}
//--------------------------------------------------------------- 8 --
FileClose( Handle ); // Закрываем файл
PlaySound("bulk.wav"); // Звуковое сопровождение
WindowRedraw(); // Перерисовываем объекты
return; // Выход из start()
}
//--------------------------------------------------------------- 9 --

В блоке 2-3 эксперта открыты и описаны используемые переменные. В блоке 3-4 осуществляется попытка открытия файла и производится анализ результатов этой операции. Для открытия файла используется функция FileOpen():

   Handle=FileOpen(File_Name,FILE_CSV|FILE_READ,";");// Открытие файла

Попытка открытия файла не всегда заканчивается успехом. Неудача может быть в том случае, если файла с указанным именем не существует. При неудачной попытке открыть файл (файловый описатель - отрицательное число) выводится необходимое сообщение пользователю и исполнение функции start() заканчивается.

В случае успешного открытия файла управление передаётся оператору цикла while (блоки 4-8). На каждой итерации этого цикла выполняется чтение данных из файла (блок 5-6), преобразование и анализ этих данных (блок 6-7) и создание графического объекта с координатами и свойствами, соответствующими последним прочитанным данным (блок 7-8).

Выполнение цикла while происходит до тех пор, пока файловый указатель не переместится в конец файла, т.е. когда справа от файлового указателя уже не останется каких-либо данных. Для анализа положения файлового указателя используется функция FileIsEnding().

Функция FileIsEnding()

bool FileIsEnding(int handle)

Функция возвращает TRUE, если файловый указатель находится в конце файла, иначе возвращает FALSE. Чтобы получить информацию об ошибке, необходимо вызвать функцию GetLastError(). В случае достижения конца файла в процессе чтения функция GetLastError() вернет ошибку ERR_END_OF_FILE (4099).

Параметры:

handle - файловый описатель, возвращаемый функцией FileOpen().


Представленное решение (timetablenews.mq4) предусматривает, что в рабочем файле News.csv может быть записано неопределённое количество новостей. В приведенном примере (Рис. 149) файл News.csv содержит пять строк, соответствующих пяти событиям (новостям). В общем случае количество строк может составлять от 0 до 20-30 в зависимости от количества реальных событий, которые должны произойти в этот день.

Чтение записей из файла (идентифицируемого по значению переменной Handle) осуществляется в блоке 5-6:

      Str_DtTm =FileReadString(Handle);// Дата и время события(дата)
Text =FileReadString(Handle);// Текст описания события
if(FileIsEnding(Handle)==true) // Файловый указатель в конце
break; // Выход из чтения и рисования

В первой и второй строках блока 5-6 производится чтение данных из файла до ближайшего разделителя. В третьей и четвёртой строках выполняется проверка: не находится ли файловый указатель в конце файла. Если нет, то далее в цикле на основе двух прочитанных значений создаются графические объекты. Если бы изначально было точно известно количество записей, то анализ, выполняемый в третьей и четвёртой строках был бы не нужен. В этом случае можно было бы жёстко задать количество итераций в цикле (например, 5) и не выполнять лишнюю проверку.

Однако, в данном случае общее количество записей неизвестно. Вместе с тем, в данном примере каждое событие описывается двумя значениями, составляющими одну строку вида: значение, файловый разделитель, значение, признак окончания строки. В данном случае полагается, что если есть одна запись (первое значение в строке), то есть и другая запись; но если нет первой записи, то нет и второй, а значит нет и события, поэтому создавать графический объект не нужно. Если обеих записей или какой-либо одной из них не существует, то при попытке чтения записи файловый указатель переместится в конец файла, т.е. такое место, где справа от указателя нет никаких данных. Проверка в строках 3 и 4 позволяет выявить этот факт. Если указанную проверку (две последние строки в блоке 5-6) удалить, то в процессе исполнения программы будет создан лишний графический объект. И лишь после этого сработает условие окончания цикла while и управление будет передано в блок 8-9. В общем случае при составлении алгоритмов чтения файлов необходимо учитывать логику представления данных в файле, порядок следования записей и разделителей, количество строк и пр. Для каждого конкретного случая должен быть определён конкретный алгоритм.

Данные, прочитанные из файла, имеют строковый тип. Для того, чтобы воспользоваться полученными значениями для создания графических объектов, необходимо преобразовать данные в нужный тип. В блоке 6-7 первое (прочитанное в очередной строке) значение преобразуется в значение типа datetime и в дальнейшем используется в качестве координаты графического объекта, поставленного в соответствие событию. Первые три символа из второго прочитанного строкового значения сравниваются с первой и второй тройкой символов в названии финансового инструмента. Если есть совпадение, то графический объект получает соответствующие свойства: стиль линии - сплошная и цвет - красный (блок 7-8). В других случаях объекты отображаются оранжевым пунктиром. В результате исполнения скрипта в окне финансового инструмента можно наблюдать линии новостей:


Рис. 150. Графические объекты в окне финансового инструмента после исполнения timetablenews.mq4.

Таким образом, скрипт может быть исполнен в окне любого валютного инструмента, при этом в каждом окне сплошная красная вертикальная линия будет отражать события, касающиеся этого инструмента, а пунктирные линии - события по другим инструментам. Для отображения текстового описания объекта необходимо включить галочку опции "Показывать описания объектов" в окне Свойства финансового инструмента (F8) > Общие.

В блоке 8-9, после того, как задача решена, а именно все необходимые объекты созданы, ранее открытый файл закрывается. Файл необходимо закрывать для того, чтобы, во-первых, не расходовать лишние ресурсы компьютера, а во-вторых, для того, чтобы обеспечить другим программам доступ к файлу в режиме записи. Нормальной следует считать практику закрытия файла сразу после того, как все данные из него прочитаны (или записаны в файл) и в использовании файла больше нет необходимости. Закрытие файла выполняется с помощью функции FileClose().

Функция FileClose()

 void FileClose(int handle)

Функция выполняет закрытие файла, ранее открытого функцией FileOpen().

Параметры:

handle - файловый описатель, возвращаемый функцией FileOpen().


Для того, чтобы у трейдера была возможность практически использовать скрипт timetablenews. mq4, в его распоряжении должен быть способ создания файла, содержащего расписание новостей на некоторый период. Такой файл может быть создан с помощью любого текстового редактора, однако в этом случае остаётся возможность ошибки (иногда можно ошибочно не указать разделитель). Рассмотрим вариант создания рабочего файла средствами MQL4.

Задача 37. Представить код эксперта для создания файла расписания новостей.

В общем случае эксперт может быть предназначен для создания файла, содержащего любое количество новостей. Рассматриваемый здесь эксперт createfile.mq4 создаёт рабочий файл, содержащий сведения не более, чем о пяти событиях.

//--------------------------------------------------------------------
// createfile.mq4
// Предназначен для использования в качестве примера в учебнике MQL4.
//--------------------------------------------------------------- 1 --
extern string Date_1=""; // 2007.05.11 10:30
extern string Text_1=""; // CHF Разрешения на строительство
extern string Date_2=""; // 2007.05.11 12:00
extern string Text_2=""; // GBP Ставка рефинансирования,2%,2.5%
extern string Date_3=""; // 2007.05.11 13:15
extern string Text_3=""; // EUR Встреча управляющих банков G10
extern string Date_4=""; // 2007.05.11 15:30
extern string Text_4=""; // USD Количество безработных в США
extern string Date_5=""; // 2007.05.11 18:30
extern string Text_5=""; // JPY Промышленное производство
//--------------------------------------------------------------- 2 --
int start() // Спец. функция start
{
//--------------------------------------------------------------- 3 --
int Handle, // Файловый описатель
Qnt_Symb; // Количество записанных симв.
string File_Name="News.csv"; // Имя файла
string Erray[5,2]; // Массив на 5 новостей
//--------------------------------------------------------------- 4 --
Erray[0,0]=Date_1; // Заполняем массив значениями
Erray[0,1]=Text_1;
Erray[1,0]=Date_2;
Erray[1,1]=Text_2;
Erray[2,0]=Date_3;
Erray[2,1]=Text_3;
Erray[3,0]=Date_4;
Erray[3,1]=Text_4;
Erray[4,0]=Date_5;
Erray[4,1]=Text_5;
//--------------------------------------------------------------- 5 --
Handle=FileOpen(File_Name,FILE_CSV|FILE_WRITE,";");//Открытие файла
if(Handle==-1) // Неудача при открытии файла
{
Alert("Ошибка при открытии файла. ",// Сообщение об ошибке
"Возможно, файл занят другим приложением");
PlaySound("Bzrrr.wav"); // Звуковое сопровождение
return; // Выход из start()
}
//--------------------------------------------------------------- 6 --
for(int i=0; i<=4; i++) // Цикл по всему массиву
{
if(StringLen(Erray[i,0])== 0 || // Если значение первой или ..
StringLen(Erray[i,1])== 0) // ..второй перемен. не введено
break; // .. то выход из цикла
Qnt_Symb=FileWrite(Handle,Erray[i,0],Erray[i,1]);//Запись в файл
if(Qnt_Symb < 0) // Если не получилось
{
Alert("Ошибка записи в файл ",GetLastError());// Сообщение
PlaySound("Bzrrr.wav"); // Звуковое сопровождение
FileClose( Handle ); // Закрываем файл
return; // Выход из start()
}
}
//--------------------------------------------------------------- 7 --
FileClose( Handle ); // Закрываем файл
Alert("Файл ",File_Name," создан.");// Сообщение
PlaySound("Bulk.wav"); // Звуковое сопровождение
return; // Выход из start()
}
//--------------------------------------------------------------- 8 --

Исходные данные вводятся в программу с помощью внешних переменных типа string (блок 1-2). В блоке 3-4 открыты и описаны переменные. Для удобства обработки в программе введенные данные записываются (блок 4-5) в строковый массив Erray[][]. Каждое событие (сведения, характеризующие новость) представлено в двух элементах массива по второму измерению. Размер первого измерения (количество строк в массиве) определяется количеством новостей, в данном случае 5. Для того, чтобы при опробовании эксперта на демо-счёте не вводить вручную все значения, можно загрузить файл настроек эксперта example_news.set; файл настроек эксперта должен находиться в каталоге Каталог_терминала\presets \.

В блоке 5-6 выполняется открытие файла. Если операция закончилась неудачей, то после сообщения пользователю функция start() заканчивает работу. Если файл открыт удачно, то управление передаётся оператору цикла for, в блок 6-7. Количество итераций в цикле ограничивается количеством новостей, а именно, числом 5. В общем случае количество вводимых значений, размер массива Erray и количество итераций можно увеличить до желаемого.

На каждой итерации цикла выполняется проверка: не является ли какое либо из введенных значений пустым. Для этого вычисляется длина строковых значений элементов массива Erray. Если какое-то из них имеет нулевую длину, то это расценивается как отсутствие текущего и следующих сообщений, поэтому текущая итерация прерывается. До тех пор, пока не нашлось пустое значение элемента массива, выполняется запись значений двух элементов массива в файл. Для записей значений в csv-файл используется функция FileWrite():

Функция FileWrite()

 int FileWrite(int handle, ...)

Функция предназначена для записи данных в файл CSV, разделитель между данными включается автоматически. После записи в файл добавляется признак конца строки "\r\n". При выводе числовые данные преобразуются в текстовый формат (см. функцию Print()). Функция возвращает количество записанных символов или отрицательное значение, если происходит ошибка.

Параметры:

handle - файловый описатель, возвращаемый функцией FileOpen();

... - данные, разделенные запятыми. Может быть не больше 63 параметров.

Данные типов double, int автоматически преобразовываются в строку (данные типов color, datetime и bool воспринимаются как целые числа тип int, и тоже преобразовываются в строку), данные типа string выводятся как есть, без преобразования. В качестве параметра нельзя передать массивы; массивы должны выводиться поэлементно.


В рассматриваемом примере данные записываются в файл в строке:

      Qnt_Symb=FileWrite(Handle,Erray[i,0],Erray[i,1]);//Запись в файл

При записи в файл после значения Erray[i,0] будет записан разделитель (символ, используемый как разделитель, указывается в функции открытия файла FileOpen(), в данном случае ';'). После окончания исполнения функции FileWrite(), т.е. в конце записи, будет автоматически записан признак конца строки "\r\n". На всех последующих итерациях цикла for будет сделана очередная запись такого же вида. Каждая новая запись начинается с того места, где остался файловый указатель после последней записи. При этом в файл будут записаны значения следующих элементов массива Erray (индексы элементов на каждой итерации увеличиваются на 1).

Если текущая запись в файл выполнена успешно, то управление передаётся на следующую итерацию. Если же запись в файл закончилась неудачей, то после сообщения пользователю файл закрывается с помощью функции FileClose() и функция start() заканчивает работу. Если все записи в файл выполнены успешно, то после окончания исполнения цикла for управление передаётся функции закрытия файла FileClose() в блок 7-8. В этом случае выводится сообщение об успешном создании файла, после чего исполнение функции start() заканчивается. По окончании исполнения эксперта будет создан файл News.csv, представленный на Рис. 149.


Функции, применяемые для осуществления файловых операций


Функция Краткое описание
FileClose Закрытие файла, ранее открытого функцией FileOpen().
FileDelete Удаление указанного файла. Файлы могут быть удалены только в том случае, если они расположены в папке каталог_терминала\experts\files (каталог_терминала\tester\files в случае тестирования эксперта) или ее подпапках.
FileFlush Сброс на диск всех данных, оставшихся в файловом буфере ввода-вывода.
FileIsEnding Возвращает TRUE, если файловый указатель находится в конце файла, иначе возвращает FALSE. В случае достижения конца файла в процессе чтения функция GetLastError() вернет ошибку ERR_END_OF_FILE (4099)
FileIsLineEnding Возвращает TRUE, если файловый указатель находится в конце строки файла формата CSV, иначе возвращает FALSE.
FileOpen Открывает Файл для ввода и/или вывода. Возвращает файловый описатель открытого файла или -1 в случае неудачи.
FileOpenHistory Открывает файл в текущей папке истории (каталог_терминала\history\server_name) или ее подпапках. Возвращает описатель файла или -1 в случае неудачи.
FileReadArray Функция читает указанное число элементов из двоичного файла в массив. Перед чтением данных массив должен быть достаточного размера. Функция возвращает количество фактически прочитанных элементов.
FileReadDouble Функция читает число двойной точности с плавающей точкой (double) из текущей позиции бинарного файла. Размер числа может быть 8 байтов (double) или 4 байта (float).
FileReadInteger Функция читает целое число из текущей позиции бинарного файла. Размер целого числа может быть 1, 2 или 4 байта. Если размер числа не указан, система пытается прочитать как 4-байтовое целое число.
FileReadNumber Чтение числа с текущей позиции файла CSV до разделителя. Применяется только для файлов CSV.
FileReadString Функция читает строку с текущей позиции файла. Применяется как к CSV, так и к двоичным файлам. Для текстовых файлов строка будет прочитана до разделителя. Для бинарных файлов в строку будет прочитано указанное количество символов.
FileSeek Функция перемещает файловый указатель на новую позицию, которая является смещением в байтах от начала, конца или текущей позиции файла. Следующее чтение или запись происходят с новой позиции. Если перемещение файлового указателя прошло успешно, функция возвращает TRUE, иначе возвращает FALSE.
FileSize Функция возвращает размер файла в байтах.
FileTell Функция возвращает смещение текущей позицию файлового указателя от начала файла.
FileWrite Функция предназначена для записи данных в файл CSV, разделитель между данными включается автоматически. После записи в файл добавляется признак конца строки "\r\n". При выводе числовые данные преобразуются в текстовый формат. Возвращает количество записанных символов или отрицательное значение, если происходит ошибка.
FileWriteArray Функция записывает массив в бинарный файл.
FileWriteDouble Функция записывает число с плавающей запятой в двоичный файл.
FileWriteInteger Функция записывает значение целого числа в двоичный файл.
FileWriteString Функция записывает строку в двоичный файл с текущей позиции. Возвращает число фактически записанных байтов или отрицательное значение в случае ошибки.

Для получения подробного описания этих и других функций необходимо обратиться к справочной документации на MQL4.community, сайте MetaQuotes Software Corp. или к разделу "Справка" в редакторе MetaEditor.