- Способы хранения информации: текстовый и двоичный
- Запись и чтение файлов в упрощенном режиме
- Открытие и закрытие файлов
- Управление дескрипторами файлов
- Выбор кодировки для текстового режима
- Запись и чтение массивов
- Запись и чтение структур (бинарные файлы)
- Запись и чтение переменных (бинарные файлы)
- Запись и чтение переменных (текстовые файлы)
- Управление позицией внутри файла
- Получение свойств файла
- Принудительная запись кэша на диск
- Удаление и проверка на существование файла
- Копирование и перемещение файлов
- Поиск файлов и папок
- Работа с папками
- Диалог выбора файла или папки
Работа с файлами
Редко какая программа обходится без ввода-вывода данных. Мы уже знаем, что MQL-программы могут получать настройки через входные переменные и выводить информацию в журнал — последним мы пользовались практически во всех тестовых скриптах. Но этого недостаточно в большинстве случаев.
Например, довольно часть настройки программы включают объемы данных, которые нельзя уместить во входных параметрах. Или программу необходимо интегрировать с некими внешними аналитическими средствами, то есть выгружать рыночную информацию в стандартном или специализированном формате, обрабатывать и затем загружать в терминал в новом виде, в частности, как торговые сигналы, набор весов нейронной сети или коэффициенты дерева решений. Да и журнал бывает удобно вести для MQL-программы отдельный, собственный.
Наиболее универсальные возможности для подобных задач предоставляет файловая подсистема. И MQL5 API содержит широкий спектр функций по работе с файлами, включая их создание, удаление, поиск, запись и считывание. Всё это мы изучим в данной главе.
Все операции с файлами в MQL5 ограничены особой областью на диске, которая называется "песочницей". Это сделано из соображений безопасности, чтобы ни одна MQL-программа не могла использоваться в злонамеренных целях и навредить вашему компьютеру и операционной системе.
Продвинутые пользователи имеют возможность обойти это ограничение с помощью специальных мер, о которых мы расскажем чуть ниже, но делать это следует только в исключительных случаях, соблюдая меры предосторожности и принимая на себя всю ответственность.
У каждого экземпляра терминала, установленного на компьютере, корневой каталог "песочницы" располагается по пути: <папка_данных_терминала>/MQL5/Files/. Из редактора MetaEditor легко найти папку данных с помощью команды Файл -> Открыть каталог данных. При наличии достаточных прав доступа на компьютере этот каталог, как правило, совпадает с тем местом, куда установлен терминал. Если прав недостаточно, путь будет иметь вид:
X:/Users/<user_name>/AppData/Roaming/MetaQuotes/Terminal/<instance_id>/MQL5/Files/ |
Здесь X — литера диска, где установлена система, <user_name> — логин пользователя Windows, <instance_id> — уникальный идентификатор экземпляра терминала. Папка Users также имеет алиас "Documents and Settings".
Обратите внимание, что если подключение к компьютеру осуществляется удаленно через RDP (Remote Desktop Protocol), то в любом случае используется каталог Roaming и его подкаталоги, даже если у вас есть административные права.
Напомним, что папка MQL5 в каталоге данных — это то место, где хранятся все MQL-программы: как их исходные коды, так и скомпилированные ex5-файлы. Каждый тип MQL-программ — индикаторы, эксперты, скрипты и прочие — имеет в папке MQL5 выделенную вложенную папку. Таким образом, папка Files для рабочих файлов находится с ними по соседству.
Помимо этой "персональной" "песочницы" каждой копии терминала на компьютере имеется общая, разделяемая "песочница" для всех терминалов: через неё они могут "общаться". Путь к ней "пролегает" через домашнюю папку пользователя Windows и может отличаться в зависимости от версии операционной системы. Например, в стандартных установках Windows 7, 8, 10 он имеет вид:
X:/Users/<user_name>/AppData/Roaming/MetaQuotes/Terminal/Common/Files/ |
Редактор MetaTrader и в данном случае облегчает поиск папки: достаточно выполнить команду Файл -> Открыть общую папку данных, и вы окажетесь внутри папки Common.
Следует напомнить, что некоторые типы MQL-программ (эксперты и индикаторы) способны выполняться не только в терминале, но и тестере. При работе в нем общая "песочница" остается доступной, а вместо "песочницы" отдельного экземпляра используется папка внутри агента тестирования. Как правило, она имеет вид:
X:/<путь_к_терминалу>/Tester/Agent-IP-port/MQL5/Files/ |
Из самой MQL-программы это обстоятельство незаметно, то есть все файловые функции работают совершенно одинаково, однако с точки зрения пользователя может сложиться впечатление, что существует какая-то проблема. Например, если программа сохранит результаты своей работы в файл, тот будет удален в папке агента тестера после окончания прогона (как будто файл и не создавался). Такое поведение задумано с целью предотвратить утечку потенциально ценных данных одной программы в другую программу, которая может тестироваться на том же агенте спустя какое-то время (тем более что агенты могут быть в общем доступе). Для передачи файлов на агенты и возврата результатов с агентов в терминал предусмотрены другие технологии, о которых мы поговорим в пятой части книги.
Для того чтобы обойти ограничение на "песочницу", можно воспользоваться способностью Windows назначать символические ссылки на объекты файловой системы. В нашем случае, для перенаправления доступа к папкам на локальном компьютере лучше всего подходят так называемые соединения (junction). Они создаются с помощью следующей команды (имеется в виду командная строка Windows):
mklink /J new_name existing_target |
Параметр new_name — это имя новой виртуальной "папки", которая будет указывать на реальную папку existing_target.
Для создания соединений к внешним папками вне "песочницы" рекомендуется завести внутри MQL5/Files выделенную папку, например, Links. Затем зайдя в неё можно выполнить вышеуказанную команду, выбрав new_name и подставив реальный путь вне "песочницы" в качестве existing_target. Например, следующая команда создаст в папке Links новую ссылку с именем Settings, которая обеспечит обращение к папке MQL5/Presets:
mklink /J Settings "..\..\Presets\" |
Относительный путь "..\..\" предполагает, что команда выполняется в указанной папке MQL5/Files/Links. Сочетание двух точек ".." обозначает переход из текущей папки в родительскую. Указанная дважды, эта комбинация предписывает два раза подняться наверх по иерархии пути. В результате целевая папка (existing_target) сформируется как MQL5/Presets. Но в параметре existing_target можно задавать и абсолютный путь.
Удалить символические ссылки можно как обычные файлы (но, разумеется, следует предварительно убедиться, что удаляется именно папка со значком стрелочки в её левом нижнем углу, т.е. ссылка, а не оригинальная папка). Рекомендуется делать это сразу же после того, как необходимость в прорыве за границу "песочницы" отпала. Дело в том, что созданные виртуальные папки становятся доступны всем MQL-программам, а не только вашей, и не известно, как дополнительную свободу могу использовать чужие программы.
Во многих разделах главы речь пойдет об именах файлов. Они выступают в роли идентификаторов элементов файловой системы и для них существуют похожие правила, в том числе и кое-какие ограничения.
Напомним, что имя файла не может содержать некоторые символы, которые играют особые роли в файловой системе ('<', '>', '/', '\\', '"', ':', '|', '*', '?'), а также любые символы с кодами от 0 до 31 включительно.
Также в операционной системе зарезервированы для специального применения и не могут использоваться следующие имена файлов: CON, PRN, AUX, NUL, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9, LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, LPT9.
Следует учесть, что файловая система Windows не "видит" принципиальной разницы между буквами в разных регистрах, поэтому имена вроде "Name", "NAME", "name" ссылаются на один и тот же элемент.
В качестве символа разделителя между составными частями пути (вложенными папками и файлом) Windows позволяет использовать как обратную косую черту '\\', так и прямую '/'. Однако обратный слэш требуется экранировать (то есть, фактически писать его дважды) в строках MQL5, потому что сам символ '\' является специальным: с помощью него строятся последовательности управляющих символов, такие как '\r', '\n', '\t' и другие (см. раздел Символьные типы). Например, следующие пути эквивалентны: "MQL5Book/file.txt" и "MQL5Book\\file.txt".
Символ точки '.' служит разделителем между именем и расширением. Если элемент файловой системы имеет несколько точек в своем идентификаторе, то расширением считается фрагмент справа от самой правой точки, а все, что слева от неё, является именем. Название (перед точкой) или расширение (после точки) может быть пустым. Например, вот имя файла без расширения — "text", а вот файл без имени (только с расширением) — ".txt".
Общая длина пути и имени файла в Windows имеет ограничения. При этом для управления файлами в MQL5 следует учитывать, что к их пути и имени будет спереди добавлен путь к самой "песочнице", то есть на названия файловых объектов в вызовах MQL-функций будет отведено еще меньше места. По умолчанию, общее ограничение длины составляет системную константу MAX_PATH, равную 260. Начиная с Windows 10 (сборки 1607) вы можете увеличить этот предел до 32767. Для этого необходимо сохранить следующий текст в reg-файл и запустить его, добавив в Реестр Windows.
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem]
"LongPathsEnabled"=dword:00000001
Для других версий Windows можно воспользоваться "обходными маневрами" из командной строки. В частности, сократить путь можно с помощью рассмотренных выше соединений (создав виртуальную папку с кратким путем). Также можно применить команду оболочки — subst, например, subst z: с:\very\long\path (см. подробности в справке Windows).