// File Read Write.mq4 // Скрипт. Положить в папку experts\script #property copyright "mandorr@gmail.com" #include <WinUser32.mqh> #import "kernel32.dll" int _lopen (string path, int of); int _lcreat (string path, int attrib); int _llseek (int handle, int offset, int origin); int _lread (int handle, string buffer, int bytes); int _lwrite (int handle, string buffer, int bytes); int _lclose (int handle); #import void start() { string path="C:\Text.txt"; string title="Чтение из файла"; string msg; int result; int handle=_lopen(path,4); if (handle<0) { msg="Ошибка открытия файла"; MessageBox(msg,title,MB_OK|MB_ICONERROR); return; } result=_llseek (handle,0,0); string buffer=""; string char="x"; int count=0; result=_lread (handle,char,1); while (result>0) { buffer=buffer+char; char="x"; count++; result=_lread (handle,char,1); } result=_lclose (handle); msg="Число считанных байт: "+count+" \n" +"Все содержимое файла:\n\n"+StringTrimRight(buffer); MessageBox(msg,title,MB_OK|MB_ICONINFORMATION); } [/code] Дальше для тех, кому интересно, как это работает: // _lopen : Откpывает указанный файл. Возвpащает: описатель файла. // _lcreat : Создает указанный файл. Возвpащает: описатель файла. // _llseek : Устанавливает указатель в откpытом файле. Возвpащает: // новое смещение указателя. // _lread : Считывает из откpытого файла указанное число байт. // Возвpащает: число считанных байт; 0 - если конец файла. // _lwrite : Записывает данные из буфеpа в указанный файл. Возвpащает: // число записанных байт. // _lclose : Закpывает указанный файл. Возвpащает: 0. // В случае неуспешного завеpшения все функции возвращают значение // HFILE_ERROR=-1. // path : Стpока, опpеделяющая путь и имя файла. // of : Способ открытия. // attrib : 0 - чтение или запись; 1 - только чтение; 2 - невидимый или // 3 - системный. // handle : Файловый описатель. // offset : Число байт, на котоpое пеpемещается указатель. // origin : Указывает начальную точку и напpавление пеpемещения: 0 - // впеpед от начала; 1 - с текущей позиции; 2 - назад от конца файла. // buffer : Пpинимающий/записываемый буфеp. // bytes : Число считываемых байт. // Способы открытия (параметр of): // int OF_READ =0; // Открыть файл только для чтения // int OF_WRITE =1; // Открыть файл только для записи // int OF_READWRITE =2; // Открыть файл в режиме запись/чтение // int OF_SHARE_COMPAT =3; // Открывает файл в режиме общего // совместного доступа. В этом режиме любой процесс может открыть данный // файл любое количество раз. При попытке открыть этот файл в любом другом // режиме, функция возвращает HFILE_ERROR. // int OF_SHARE_DENY_NONE =4; // Открывает файл в режиме общего доступа // без запрета на чтение/запись другим процессам. При попытке открытия // данного файла в режиме OF_SHARE_COMPAT, функция возвращает HFILE_ERROR. // int OF_SHARE_DENY_READ =5; // Открывает файл в режиме общего доступа с // запретом на чтение другим процессам. При попытке открытия данного файла // с флагами OF_SHARE_COMPAT и/или OF_READ или OF_READWRITE, функция // возвращает HFILE_ERROR. // int OF_SHARE_DENY_WRITE=6; // Тоже самое, только с запретом на запись. // int OF_SHARE_EXCLUSIVE =7; // Запрет текущему и другим процессам на // доступ к этому файлу в режимах чтения/записи. Файл в этом режиме можно // открыть только один раз (текущим процессом). Все остальные попытки // открытия файла будут провалены.Сделал покрасивше.
Примечание. В словаре MetaEditor читаем: "Длина строковой константы - от 0 до 255 символов. Если длина строковой константы превосходит максимальную, лишние символы справа отбрасываются, и компилятор выдает соответствующее предупреждение".
В функциях WriteFile и ReadFile есть грубые ошибки, но тем не менее фунции отлично работают. Видимо это глюк метатрейдера. Не исключено, что начиная с некоторого билда, использование этих функций будет приводить к зависанию терминала. Для устойчивости, надо считывать/записывать блоками не более 250 символов. Тогда всё будет гут.
Примечание. В словаре MetaEditor читаем: "Длина строковой константы - от 0 до 255 символов. Если длина строковой константы превосходит максимальную, лишние символы справа отбрасываются, и компилятор выдает соответствующее предупреждение".
пожалуй лучше использовать API
пожалуй лучше использовать API
Испугался? Всё не так уж и страшно. Лекарство я описал. Зато через импорт быстрее и надежнее. И красивее (если кому-то существенно).
А что собственно понимается под загадочной абревиатурой API? Особенно в сочетании со словами "лучше использовать" .. .
Нужто MetaTrader 4 API?
пожалуй лучше использовать API
Испугался? Всё не так уж и страшно. Лекарство я описал. Зато через импорт быстрее и надежнее. И красивее (если кому-то существенно).
А что собственно понимается под загадочной абревиатурой API? Особенно в сочетании со словами "лучше использовать" .. .
по поводу API вы шутите ? поисковые системы могут помочь! - но посылать к поисковику это грубо :)
API это Aplication Programm Interface - стандарт WINDOWS
в двух словах набор функций, которые реализованы через вызовы в DLL - фактически обращение к ядру операционной системы
причем не обязательно к "kernel32.dll" :)
думаю вы знаете что можно вызывать и собственные DLL это фактически аналогично только уже вызов не к ядру
а к вашему модулю!
#import "kernel32.dll"
int _lopen (string path, int of);
...
int _lclose (int handle);
#import
собственно это и есть вызовы через API
Правда многие программисты даже не знают что такое API , просто пишут на более высокоуровневых языках
например вызываете WriteFile и не паритесть знаниями API правда рано или поздно
эта функция обратиться чеез API к WINDOWS
все приличные языки в реде WINOWS поддерживают вызовы DLL
можно и блоками по 250 байт :) но обычно лень дробить выходные данные на блоки
а если у функции еще и глюки :) , можно более прямую дорогу найти и уже без глюков
Вопрос, близкий к теме:
Каким образом можно получить то, что в документации по MQL называется
"Директория, из которой запущен клиентский терминал terminal_dir"
Казалось, бы в документации столько ссылок на имя этой директории,
что получить его- раз плюнуть.
Но не нашел. Или не там искал?
string TerminalPath( | ) |
Например прочитать файл из папки символсетов:
string text=ReadFile(TerminalPath()+"\symbolsets\05052008.set");
Спасибо. Ну точно, плохо искал.
Кстати, обратите внимание на терминологический разнобой.
"Директория, из которой запущен клиентский терминал terminal_dir"
и
"string TerminalPath( )
Возвращает директорий, из которого запущен клиентский терминал"
Причем это единственный случай в хэлпе по MQL, где это слово применяется в мужском роде.
Но это уже придирка к авторам МТ :-)
В новых билдах эти функции уже не работают.
Кто нибудь знает как это исправить?
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
В окне "Инструментарий" редактора MetaEditor для функции FileOpen читаем:
... файлы могут открываться только в папке каталог_терминала\experts\files (каталог_терминала\tester\files в случае тестирования эксперта) или ее подпапках...
И нет режима совместного доступа к открытому файлу. По крайней мере не указан явно.
А мне вот хочется писать куда хочу и читать откуда хочу. Да еще и передавать данные из одного работающего советника в другой работающий советник через файл.
Я тут уже просил поковырять системные библиотеки на предмет использования файловых операций в советнике. Да видимо некому. Хотя функцию SendMessage из библиотеки Shell32.dll вроде как обсудили, правда с дельфийским уклоном.
Так вот, функции файловых операций используются в системной библиотеке kernel32.dll и её то мы импортируем в советник. Код приведен ниже. Создайте файл "C:\Text.txt", запишите в него немного текста. Запустите приведенный ниже скрипт. Скрипт считывает все содержимое файла. Добавить немного проверки на символы разделители и на символы конца строки, немного вишневого сиропа - и готова функция ReadLine ...
Дальше для тех, кому интересно, как это работает:
// _lopen : Откpывает указанный файл. Возвpащает: описатель файла.
// _lcreat : Создает указанный файл. Возвpащает: описатель файла.
// _llseek : Устанавливает указатель в откpытом файле. Возвpащает: новое смещение указателя.
// _lread : Считывает из откpытого файла указанное число байт. Возвpащает: число считанных байт; 0 - если конец файла.
// _lwrite : Записывает данные из буфеpа в указанный файл. Возвpащает: число записанных байт.
// _lclose : Закpывает указанный файл. Возвpащает: 0.
// В случае неуспешного завеpшения все функции возвращают значение HFILE_ERROR=-1.
// path : Стpока, опpеделяющая путь и имя файла.
// of : Способ открытия.
// attrib : 0 - чтение или запись; 1 - только чтение; 2 - невидимый или 3 - системный.
// handle : Файловый описатель.
// offset : Число байт, на котоpое пеpемещается указатель.
// origin : Указывает начальную точку и напpавление пеpемещения: 0 - впеpед от начала; 1 - с текущей позиции; 2 - назад от конца файла.
// buffer : Пpинимающий/записываемый буфеp.
// bytes : Число считываемых байт.
// Способы открытия (параметр of):
// int OF_READ = 0; // Открыть файл только для чтения
// int OF_WRITE = 1; // Открыть файл только для записи
// int OF_READWRITE = 2; // Открыть файл в режиме запись/чтение
// int OF_SHARE_COMPAT = ; // Открывает файл в режиме общего совместного доступа. В этом режиме любой процесс может открыть данный файл любое количество раз. При попытке открыть этот файл в любом другом режиме, функция возвращает HFILE_ERROR.
// int OF_SHARE_EXCLUSIVE =16; // Запрет текущему и другим процессам на доступ к этому файлу в режимах чтения/записи. Файл в этом режиме можно открыть только один раз (текущим процессом). Все остальные попытки открытия файла будут провалены.
// int OF_SHARE_DENY_WRITE=32; // Открывает файл в режиме общего доступа с запретом на запись другим процессам. При попытке открытия данного файла с флагами OF_SHARE_COMPAT и/или OF_WRITE или OF_READWRITE, функция возвращает HFILE_ERROR.
// int OF_SHARE_DENY_READ =48; // Открывает файл в режиме общего доступа с запретом на чтение другим процессам. При попытке открытия данного файла с флагами OF_SHARE_COMPAT и/или OF_READ или OF_READWRITE, функция возвращает HFILE_ERROR.
// int OF_SHARE_DENY_NONE =64; // Открывает файл в режиме общего доступа без запрета на чтение/запись другим процессам. При попытке открытия данного файла в режиме OF_SHARE_COMPAT, функция возвращает HFILE_ERROR.