Write to file outside of MT4 folders

 

Hello,

I was able to read from a file outside of MT4 folders using windows API but when I'm trying to write there are spaces in between each letters. It's an old code I found online and tried to fix. I'm guessing it has something to do with the MulDiv function but not sure. Can you please take a look?

#define GENERIC_READ    0x80000000
#define GENERIC_WRITE   0x40000000
#define FILE_SHARE_READ         0x00000001
#define FILE_SHARE_WRITE        0x00000002

#define CREATE_NEW              1
#define CREATE_ALWAYS           2
#define OPEN_ALWAYS             4
#define OPEN_EXISTING           3
#define TRUNCATE_EXISTING       5

#define FILE_BEGIN              0
#define FILE_CURRENT            1
#define FILE_END                2

#define INVALID_HANDLE_VALUE    -1
#import "kernel32.dll"
 
   int CreateFileW(string Filename, int AccessMode, int ShareMode, int PassAsZero, int CreationMode, int FlagsAndAttributes, int AlsoPassAsZero);
   int ReadFile(int FileHandle, int BufferPtr, int BufferLength, int & BytesRead[], int PassAsZero);
   int WriteFile(int FileHandle, int BufferPtr, int BufferLength, int & BytesWritten[], int PassAsZero);
   int SetFilePointer(int FileHandle, int Distance, int PassAsZero, int FromPosition);
   int GetFileSize(int FileHandle, int PassAsZero);
   int CloseHandle(int FileHandle);

   bool DeleteFileA(string Filename);

  int MulDiv(string X, int N1,int N2);
   // Used for temporary conversion of an array into a block of memory, which
   // can then be passed as an integer to ReadFile
   int LocalAlloc(int Flags, int Bytes);
   int RtlMoveMemory(int DestPtr, double & Array[], int Length);
   int LocalFree(int lMem);

   // Used for converting the address of an array to an integer 
   int GlobalLock(double & Array[]);
   bool GlobalUnlock(int hMem);
#import

int OpenNewFileForWriting(string FileName, bool ShareForReading = false)
{
   int ShareMode = 0;
   if (ShareForReading) ShareMode = FILE_SHARE_READ;

return CreateFileW(FileName, GENERIC_WRITE /*GENERIC_READ*/, 3 /*SHARE READ|WRITE*/, 0, CREATE_ALWAYS, 0, 0);
  // return (CreateFileA(FileName, GENERIC_WRITE, ShareMode, 0, CREATE_ALWAYS, 0, 0));
}

bool IsValidFileHandle(int FileHandle)
{
   return (FileHandle != INVALID_HANDLE_VALUE);
}

void CloseFile(int FileHandle)
{
   CloseHandle(FileHandle);
}

bool WriteToFile(int FileHandle, string DataToWrite)
{
   // Receives the number of bytes written to the file. Note that MQL can only pass 
   // arrays as by-reference parameters to DLLs
  int BytesWritten[1] = {0};

   // Get the length of the string 
   int szData = StringLen(DataToWrite);
Print(szData);
Print(DataToWrite);
   // Do the write 
   WriteFile(FileHandle, MulDiv(DataToWrite,1,1), szData, BytesWritten, 0);
   
   Print("BytesWritten = " + BytesWritten[0]);
   // Return true if the number of bytes written matches the expected number 
   return (BytesWritten[0] == szData);   
}

int start()
{
   string strTestFilename = "C:\\test2.txt";


   Print("About to write some example data to " + strTestFilename + "...");

   // Write some CRLF-terminated lines to the test file 
   int fWrite = OpenNewFileForWriting(strTestFilename, true);
   if (!IsValidFileHandle(fWrite))
   {
      Print("Unable to open " + strTestFilename + " for writing");
   } else {
      if((WriteToFile(fWrite, "Test12345678"))==TRUE) {
      Print("write ok"); 
      } else { Print("write not ok");  }
    }

This is how the results look:

while it should be: Test12345678

Thanks

 
This looks like a problem with ASCII (8 bit char) and 16 bit, wide char. (UTF8,...)
 
Carl Schreiber:
This looks like a problem with ASCII (8 bit char) and 16 bit, wide char. (UTF8,...)

Thanks. Any ideas how to fix it or where I should look?

 
  • Why are you using
DeleteFileA()

instead of:

DeleteFileW()?
  • I use Notepad++ there you can change the encoding and the char-sets..
 
Carl Schreiber:
  • Why are you using

instead of:

  • I use Notepad++ there you can change the encoding and the char-sets..

Actually I'm not using the DeleteFile function, just left it there from the old code. 

I checked the text file created by the script and it's in unicode format. 

 
nolambo:

Actually I'm not using the DeleteFile function, just left it there from the old code. 

I checked the text file created by the script and it's in unicode format. 


So I added the *2 multiplier to the below line and now at least the full string got written to the file, but still with the spaces. It's still not good, because now my read function reads only the first letter ('T') from this file.

   // Get the length of the string 
   int szData = StringLen(DataToWrite)*2;

It looks like this:

Any ideas?

 

Try to change this:

int WriteFile(int FileHandle, int BufferPtr, int BufferLength, int & BytesWritten[], int PassAsZero);

into e.g.

int WriteFile(int FileHandle, uchar BufferPtr, int BufferLength, int & BytesWritten[], int PassAsZero);
 

An alternative methodology:

1. Write the file using standard MQL file handling into an MT4 safe place.

2. Copy the file using whichever of these two makes sense:

// Unicode
bool CopyFileW(string lpExistingFileName,string lpNewFileName,bool bFailIfExists);
// ANSI
bool CopyFileA(string lpExistingFileName, string lpNewFileName, bool failIfExists); 
 

Thank you both for the help. It works great with CopyFileW.

 

I am trying to export a CSV file to outside of terminal folder (E://Test) with following code. But unable to export.

Can someone help me?


//+------------------------------------------------------------------+

//|                                           data writer plus 1.mq4 |

//|                                               Copyright © 2009,  |

//|                                                                  |

//+------------------------------------------------------------------+

/*This version of indicator will export all bar data in the current cart 

  no mather its newest completed one or oldest one*/

#property copyright "Copyright © 2009, "

#property link      ""



#property indicator_chart_window

#define c 6

#define e 7



//---- input parameters

extern bool      show_comment=true;

extern string InpDirectoryName="E:\\Test";



string namafile="";

string date="";

string time="";

string high="";

string low="";

string close="";

string open="";

string volume="";

string a=",";

int    handlefile=0;

int    b=0;

int    d=0;

int    bar=0;

int    res=0;

bool   writefile=false;

//+------------------------------------------------------------------+

//| Custom indicator initialization function                         |

//+------------------------------------------------------------------+

int init()

  {

//---- 

//----

   return(0);

  }

//+------------------------------------------------------------------+

//| Custom indicator deinitialization function                       |

//+------------------------------------------------------------------+

int deinit()

  {

//----

//----

   if(show_comment) Comment(" ");

   return(0);

  }

//+------------------------------------------------------------------+

//| Custom indicator iteration function                              |

//+------------------------------------------------------------------+

int start()

  {

   if(show_comment) mycomment();

   if(bar==Bars) return(0);

   //namafile="_data of "+Symbol()+" period M"+Period()+".csv";

   namafile=Symbol()+"_SPOT.csv";

   //handlefile=FileOpen(namafile, FILE_CSV|FILE_WRITE, " ");

   handlefile=FileOpen(InpDirectoryName+"//"+namafile, FILE_CSV|FILE_WRITE, " ");

   if(handlefile>0)

     { 

      for(int i=Bars-1; i>=1; i--)

         {

          date=TimeToStr(Time[i], TIME_DATE);

          time=TimeToStr(Time[i], TIME_MINUTES);

          open=DoubleToStr(Open[i], Digits);

          high=DoubleToStr(High[i], Digits);

          low=DoubleToStr(Low[i], Digits);

          close=DoubleToStr(Close[i], Digits);

          volume=DoubleToStr(Volume[i], 0);

          writefile=FileWrite(handlefile, date+a+time+a+open+a+high+a+low+a+close+a+volume);

          }

      }

    else

      {

       for(i=Bars-1; i>=1; i--)

          {

           date=TimeToStr(Time[i], TIME_DATE);

           time=TimeToStr(Time[i], TIME_MINUTES);

           open=DoubleToStr(Open[i], Digits);

           high=DoubleToStr(High[i], Digits);

           low=DoubleToStr(Low[i], Digits);

           close=DoubleToStr(Close[i], Digits);

           volume=DoubleToStr(Volume[i], 0);

           writefile=FileWrite(handlefile, date+a+time+a+open+a+high+a+low+a+close+a+volume);

          }

       if(writefile) d=e;

      } 

//----

   if(writefile) FileClose(handlefile);  

   return(0);

  }

//+------------------------------------------------------------------+

//| my comment                                                       |

//+------------------------------------------------------------------+

string mycomment()

  {

   date=TimeToStr(Time[1], TIME_DATE);

   time=TimeToStr(Time[1], TIME_MINUTES);

   open=DoubleToStr(Open[1], Digits);

   high=DoubleToStr(High[1], Digits);

   low=DoubleToStr(Low[1], Digits);

   close=DoubleToStr(Close[1], Digits);

   volume=DoubleToStr(Volume[1], 0);

   Comment("data writer plus ", Symbol(), " period M", Period(),"\n\n", "LAST BAR DATA : \n", "date   =  ",date,"\n",

           "time   =  ",time,"\n","high   =  ",high,"\n", "low    =  ",low,"\n", "volume =  ",volume);

   return("");

  } 

 
Ramu Bingi #: I am trying to export a CSV file to outside of terminal
  1. Stop trying. The function can only write to the file folder (and sub-folders).

  2. Create a junction.