Запись и чтение текстового файла.

 

Привет.

Подскажите пожалуйста как (конкретно пример) записывать .txt файл по моему пути на ПК, а не по тому который предлагает mql4.

К примеру на рабочий стол или в указанную мной папку. Мне не надо создавать, записывать и читать файл в каталоге терминала.

Спасибо!

 
amgree:

Привет.

Подскажите пожалуйста как (конкретно пример) записывать .txt файл по моему пути на ПК, а не по тому который предлагает mql4.

К примеру на рабочий стол или в указанную мной папку. Мне не надо создавать, записывать и читать файл в каталоге терминала.

Спасибо!

CreateFile(...)
WriteFile(...)
...
WinApi в помощь
 
Vladimir Simakov:
Kernel32.dll
CreateFile(...)
WriteFile(...)
...
WinApi в помощь

    СПС. Отличный пример кода! Даже с комментариями =) Я заметил что тут не принято помогать людям.

 
amgree:

    СПС. Отличный пример кода! Даже с комментариями =) Я заметил что тут не принято помогать людям.

тут принято сначала поиском пользоваться, а потом помогать если не получилось разобраться

https://www.mql5.com/ru/search#!keyword=WriteFile

 
Igor Makanu:

тут принято сначала поиском пользоваться, а потом помогать если не получилось разобраться

https://www.mql5.com/ru/search#!keyword=WriteFile

Я к сожалению весь день потратил на поиск, а результат - не рабочие библиотеки 2007-2008 года =(
 
amgree:
Я к сожалению весь день потратил на поиск, а результат - не рабочие библиотеки 2007-2008 года =(

потратил 5 секунд на поиск - перешел по ссылке из своего сообщения

проверил пример из статьи  ФАЙЛОВЫЕ ОПЕРАЦИИ ЧЕРЕЗ WINAPI

пример записи в файл работает void WriteFile (string path, string buffer) 

, потратил еще 5 минут, по моему у нас с Вами время по разному идет ;)

 
Igor Makanu:

потратил 5 секунд на поиск - перешел по ссылке из своего сообщения

проверил пример из статьи  ФАЙЛОВЫЕ ОПЕРАЦИИ ЧЕРЕЗ WINAPI

пример записи в файл работает void WriteFile (string path, string buffer) 

, потратил еще 5 минут, по моему у нас с Вами время по разному идет ;)

По Вашей ссылке не работает ни чего!

Пример:

//+------------------------------------------------------------------+
//|                                               |
//|                      Copyright © 2008, MetaQuotes Software Corp. |
//|                                       http://www.metaquotes.net/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2008, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net/"

// константы для функции _lopen
#define OF_READ               0
#define OF_WRITE              1
#define OF_READWRITE          2
#define OF_SHARE_COMPAT       3
#define OF_SHARE_DENY_NONE    4
#define OF_SHARE_DENY_READ    5
#define OF_SHARE_DENY_WRITE   6
#define OF_SHARE_EXCLUSIVE    7

#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);
   int CreateDirectoryA(string path, int & atrr[]);
#import

// _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; // Запрет текущему и другим процессам на 
// доступ к этому файлу в режимах чтения/записи. Файл в этом режиме можно 
// открыть только один раз (текущим процессом). Все остальные попытки 
// открытия файла будут провалены.
//+------------------------------------------------------------------+
//|   прочитать файл и вернуть строку с содержимым                   |
//+------------------------------------------------------------------+
string ReadFile (string path) 
  {
    int handle=_lopen (path,2);
    int read_size = 50, last = 0;           
    string char50="x                                                 ";

    if(handle<0) 
      {
        Print("Ошибка открытия файла ",path); 
        return ("");
      }
    int result=_llseek (handle,0,0);      
    if(result<0) 
      {
        Print("Ошибка установки указателя" ); 
        return ("");
      }
    string buffer="";
    int count=0;
    
    result=_lread (handle,char50,read_size);
    while(result>0 && result == read_size) 
      {
        buffer=buffer + char50;
        count++;
        result=_lread (handle,char50,read_size);
        last = result;
     }
    Print("Последний прочитанный блок имеет размер в байтах:", last);
    char50 = StringSubstr(char50,0,last);
    buffer = buffer + char50;    
    result=_lclose (handle);              
    if(result<0)  
      Print("Ошибка закрытия файла ",path);
    return (buffer);
  }
 
//+------------------------------------------------------------------+
//|  записать содержимое буфера по указанному пути                   |
//+------------------------------------------------------------------+
void WriteFile (string path, string buffer) 
  {
    int count=StringLen (buffer); 
    int result;
    int handle=_lopen (path,2);
    if(handle<0) 
      {
        handle=_lcreat (path,0);
        if(handle<0) 
          {
            Print ("Ошибка создания файла ",path);
            if (!CreateFullPath(path))
               {
               Print("Не удалось создать папку:",path);
               return;
               }
            else handle=_lcreat (path,0);   
          }
        result=_lclose (handle);
        handle = -1;
     }
    if (handle < 0) handle=_lopen (path,2);               
    if(handle<0) 
      {
        Print("Ошибка открытия файла ",path); 
        return;
      }
    result=_llseek (handle,0,0);          
    if(result<0) 
      {
        Print("Ошибка установки указателя"); 
        return;
      }
    result=_lwrite (handle,buffer,count); 
    if(result<0)  
        Print("Ошибка записи в файл ",path," ",count," байт");
    result=_lclose (handle);              
    if(result<0)  
        Print("Ошибка закрытия файла ",path);
    return;        
  }
//+------------------------------------------------------------------+
//|  создает все необходимые папки и подпапки                        |
//+------------------------------------------------------------------+
bool CreateFullPath(string path)
   {
   bool res = false;
   if (StringLen(path)==0) return(false);
   Print("Создаем путь=>",path);
//----
   string folders[];
   if (!ParsePath(folders, path)) return(false);
   Print("Всего вложенных папок:", ArraySize(folders));
   
   int empty[];
   int i = 0;
   while (CreateDirectoryA(folders[i],empty)==0) i++;
   Print("Создали папку:",folders[i]);
   i--;
   while (i>=0) 
      {
      CreateDirectoryA(folders[i],empty);
      Print("Создали папку:",folders[i]);
      i--;
      }
   if (i<0) res = true;   
//----
   return(res);
   }
   
//+------------------------------------------------------------------+
//| разбить путь на массив подпапок                                  |
//+------------------------------------------------------------------+
bool ParsePath(string & folder[], string path)
   {
   bool res = false;
   int k = StringLen(path);
   if (k==0) return(res);
   k--;

   Print("Распарсим путь=>", path);
   int folderNumber = 0;
//----
   int i = 0;
   while ( k >= 0 )
      {
      int _char = (char)StringGetChar(path, k);
      //Print("char = ",char, "=>",CharToStr(char));
      if ( _char == 92) //  обратный слеш "\"
         {
         if (StringGetChar(path, k-1)!= 92)
            {
            folderNumber++;
            ArrayResize(folder,folderNumber);
            folder[folderNumber-1] = StringSubstr(path,0,k);
            Print(folderNumber,":",folder[folderNumber-1]);
            }
         else break;         
         }
      k--;   
      }
   if (folderNumber>0) res = true;   
//----
   return(res);   
   }   
  

сохранил код как .mqh, подключил через #include в свой индикатор и ... , увы файл не создаётся и ничего вообще не происходит, даже ошибки не выдаёт!

Windows 7 x64


Вызов функции в индикаторе каждые 5 мин. :

WriteFile("C:\\Users\\Userok\\Desktop\\TEXT.txt","111");
что я делаю не так???
 
amgree:


что я делаю не так???

Статья из 2008-ого года. С тех пор MQL перешел с ANSI на Unicode. Поэтому везде, где используются строки, нужно использовать юникод. К примеру, вместо функции CreateDirectoryA использовать CreateDirectoryW. Но в коде вроде еще что-то нужно будет менять, не вникал глубоко.

 
Блин. Вы хотя бы загуглили _lopen.
This function is provided for compatibility with 16-bit versions of Windows.
Это цитата из официальных доков. Я Вам ранее писал какие функции winapi смотреть. Но Вы хотите готовый код. 
Вы уж определитесь, Вам научиться или код написать? Если первое то доки и гугл вам помогут, если второе, то на фриланс, там за Ваши деньги Вам помогут те, кому помогли доки и гугл.
 
amgree:

По Вашей ссылке не работает ни чего!

ну Вы хоть поиском научились пользоваться?  - я слукавил, но не соврал, я скопировал скрипт который админ выкладывал давно https://www.mql5.com/ru/forum/100532#comment_2957143

запустил, но к сожалению на чтение файла - увидел,  скрипт работает, на этом не стал время тратить на поиск инфы на форуме, и предложил Вам воспользоваться поиском

в ответ, Вы рассказали историю, что нет на форуме ничего , вот опять поиском воспользовался https://www.mql5.com/ru/forum/82761#comment_2452327

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

удачи!

 
amgree:

К примеру на рабочий стол или в указанную мной папку. Мне не надо создавать, записывать и читать файл в каталоге терминала.

Можно, к примеру, создать ярлык папки Files на рабочем столе или в выбранной вами папке... и все дела :)

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