mt4-5 working with files

27
MT4-5 Working with Files 1 | Page Working with files . Part I December 31, 2009 By Bogdan Baltatu, MQLmagazine editor [Versiunea romaneasca] [MQLmagazine.com in romana] [English edition] This article will be about working with files and folders in MQL5. Functions working with files in MQL5 can be divided in two groups: Functions that deal with file manipulation and status of files Functions that deal with reading and writing in files I will take every function group and describe its functionality with code examples. Functions that deal with file manipulation and status of files These functions are the ones that open, close, delete, copy, force writing, check files existance and pointer position within files. These are the functions considered by us in this category : FileClose, FileCopy, FileDelete, FileFindCLose, FileFindFirst, FileFindNext, FileFlush, FileIsEnding, FileExist, FileIsLineEnding, FileMove, FileOpen, FileSeek, FileTell Flags Part of the function presented above use flags. These flags are global integer constants defined by MQL5 and have the purpose to specify the file opening modes (text,csv,ansi,binary) and the operations done on the file (reading/writing). The table below contains the binary value but also the integer value of the identifiers, because these are important for understanding how flags work: Decimal value Binary value Flag identifier Description 1 0000000000001 FILE_READ File open for reading

Upload: ian-warren

Post on 22-Oct-2014

478 views

Category:

Documents


15 download

TRANSCRIPT

Page 1: MT4-5 Working With Files

MT4-5 Working with Files

1 | P a g e

Working with files . Part I

December 31, 2009

By Bogdan Baltatu, MQLmagazine editor

[Versiunea romaneasca] [MQLmagazine.com in romana] [English edition]

This article will be about working with files and folders in MQL5.

Functions working with files in MQL5 can be divided in two groups:

Functions that deal with file manipulation and status of files

Functions that deal with reading and writing in files

I will take every function group and describe its functionality with code examples.

Functions that deal with file manipulation and status of files

These functions are the ones that open, close, delete, copy, force writing, check files

existance and pointer position within files. These are the functions considered by us

in this category :

FileClose, FileCopy, FileDelete, FileFindCLose, FileFindFirst,

FileFindNext, FileFlush,

FileIsEnding, FileExist, FileIsLineEnding, FileMove, FileOpen, FileSeek,

FileTell

Flags

Part of the function presented above use flags. These flags are global integer

constants defined by MQL5 and have the purpose to specify the file opening modes

(text,csv,ansi,binary) and the operations done on the file (reading/writing).

The table below contains the binary value but also the integer value of the identifiers,

because these are important for understanding how flags work:

Decimal

value

Binary value Flag identifier Description

1 0000000000001 FILE_READ File open for reading

Page 2: MT4-5 Working With Files

MT4-5 Working with Files

2 | P a g e

2 0000000000010 FILE_WRITE File open for writing

4 0000000000100 FILE_BIN Binary access for

reading/writing (no strings)

8 0000000001000 FILE_CSV CSV file (Text file with elements

separated)

16 0000000010000 FILE_TXT Text file

32 0000000100000 FILE_ANSI ANSI file (one byte symbols)

64 0000001000000 FILE_UNICODE UNICODE file (two byte

symbols)

128 0000010000000 FILE_SHARE_READ Acces impartit pentru citire de

mai multe programe

256 0000100000000 FILE_SHARE_WRITE Shared access for more

programs

512 0001000000000 FILE_REWRITE Possibility to rewrite the file

with FileCopy and FileMove.

4096 1000000000000 FILE_COMMON File is in the common folder for

all MT5 client terminals

Comparing with the previous MetaQuotes language, MQL4, can be observed the

birth of new flags like the ones that give the possibility to open files in new modes

like : ANSI, text, UNICODE but also two new modes that allow writing and reading

from files even if they are opened by other programs.

A novelty brought by MetaQuotes is opening files that are in MQL5 folder and not

only in terminal_directory\experts\files as it was possible in MT4.

Functions working with files may accept flag combinations, but these flags must be

used carefully, because for instance you can’t use FILE_TXT|FILE_BIN

simultaneously because it’s impossible to open the same file in two modes. I’ll detail

the correct flag usage at the FileOpen() function.

FileOpen

The FileOpen() function sits at the base of file operations because there couldn’t be

any continuation with other operations if files can’t be created or opened.

Page 3: MT4-5 Working With Files

MT4-5 Working with Files

3 | P a g e

1

2

3

4

int FileOpen(string file_name,

int open_flags,

short delimiter //for CSV files

);

The function returns an integer (file handle) and this integer has to be memorated in

a variable because it will be used with all operations with the file, representing the

reference to the opened or created file.

The FileOpen() function has a double role because it is used for both opening and

creating files.

1

2

3

4

5

6

7

8

9

int m_handle=-1;

string m_filename="test.txt";

m_handle=FileOpen(m_filename,FILE_READ|FILE_TXT);

if (m_handle<0)

{

Print("I can't open the file.");

}

else

Print("File successfully open.");

The above code opens the test.txt file in the text mode. If the file doesn’t exist,

m_handle will remain -1, what means the file hasn’t been open yet. (Surely can’t be

opened since it doesn’t exist). If we wish to create a file we have to use FILE_WRITE

because the flag is creating the file in the same time. The created file is in the

/MQL5/Files/ folder. In the beta version, the one existing now at the time the article

is written, the files are not in the MQL5 folder that’s where you installed the

platform. To see the exact place where the files are you can use in a script the

following line:

1 Print(TerminalInfoString(TERMINAL_DATA_PATH));

Be careful using flags, because wrong use can generate errors.

FileClose

Page 4: MT4-5 Working With Files

MT4-5 Working with Files

4 | P a g e

1

2

3

void FileClose(

int file_handle

);

The file_handle parameter is the one returned by FileOpen(), in the FileOpen()

example the name of our parameter is m_handle. It’s good to reset this parameter to

-1 after we close the file if we want to check if the file is still opened. The FileClose()

function doesn’t return any result meaning that, at least theoretically the function is

successful.

FileDelete

The function deletes a file , be it in the local terminal folder or in the common folder

used by all MetaTrader5 platforms.

1

2

3

4

bool FileDelete(

string file_name // Numele fisierului care va fi sters

int common_flag=0 // Flag de localizare

);

The second parameter is optional. If it is FILE_COMMON then the function will

delete the file from the folder that’s shared by all MetaTrader5 platforms; otherwise,

it will delete the file from the local station.

The function returns true if the operation was successful, or false in case that it

failed.

Functia returneaza true daca operatiunea a fost executata cu succes sau false in caz

de operatiunea a esuat.

MetaTrader experts can be run realtime or they can be tested on historical data.

When experts are being tested on historical data the functions working with files

don’t use MQL5/files anymore, but MQL5/tester instead.

FileCopy

The function copies a folder from the local or common folder to another name

keeping the file intact.

1

2

bool FileCopy(

string src_filename, //Name of the file to be copied

Page 5: MT4-5 Working With Files

MT4-5 Working with Files

5 | P a g e

3

4

5

6

int common_flag, //Localization flag

string dst_filename, //Destination file name

int mode_flags //Access flags

);

The second parameter, common_flag, can’t be missing so when the file we want to

copy is not in the MT5 shared folder it has to be replaced with 0.

The mode_flags parameter has two options : FILE_REWRITE and/or

FILE_COMMON. If the destination file exists and we try to copy a file without

specifying FILE_REWRITE as ‘mode_flags’ parameter then the destination file will

not be overwritten by the source.

FileMove

The function’s prototype is the same as FileCopy()’s prototype. The difference is that

the FileMove() copies the source file in another location but in the same time deletes

the source. Practically the function can be used to rename an existing file.

FileFlush

The function has the role to write on the disc the data from the buffer.

1

2

3

void FileFlush(

int file_handle

);

The function has only one parameter, that being the file handle resulted by

open/creation with FileOpen().

To understand what FileFlush() is used for, we have to understand how file

reading/writing works. When a file is opened the information is copied in memory in

a buffer, because memory’s speed is higher than disk speed. A call to FileFlush() is

mandatory whenever operation is changed , from reading to writing or the other way

around.

FileIsExist

The function FileIsExist checks whether the file exists or not.

1

2

bool FileIsExist(

string file_name,

Page 6: MT4-5 Working With Files

MT4-5 Working with Files

6 | P a g e

3

4

int common_flag=0

);

The first parameter refers the name of the file, and the second parameter refers the

place where the file has to be looked for. The function can be used to limit the errors

generated by FileOpen() in the case the file doesn’t exist.

FileTell

The function returns the current position of a file pointer in an open file.

1

2

3

int FileTell(

int file_handle

);

The position is in number of bytes from the beginning of the file.

FileIsEnding

The function is used to find out whether the file end has been reached or not.

1

2

3

bool FileIsEnding(

int file_handle // Handler de fisier

);

The function is necesary because it’s important to know when the end of the file has

been touch, in the most cases when file is read entirely or when we search for

something in it.

FileIsLineEnding

The function has the same prototype as the FileIsEnding() function, just this returns

true when the end of the line is being touched instead of the end of the file. The

function can be used only for text or CSV files and the end of the line is when CR

(Carriage Return) or LF(Line Feed) is encountered. However, the function is quite

buggy at the time the article is being written.

FileSeek

The function moves the file pointer a specified number of bytes from the specified

position.

Page 7: MT4-5 Working With Files

MT4-5 Working with Files

7 | P a g e

1

2

3

4

5

void FileSeek(

long file_handle

int offset,

ENUM_FILE_POSITION origin

);

The origin can be SEEK_SET (begin of the file), SEEK_CUR (current position),

SEEK_END (sfarsitul fisierului). The offset can be either positive or negative because

the pointer can move in both directions.

The last 3 functions that are presented in this article are FileFindFirst(),

FileFindNext() and FileFindClose().

FileFindFirst

The function has the purpose to begin enumerating files in the local or common

folder with a specified wildcard.

1

2

3

4

5

long FileFindFirst(

string file_filter,

string& returned_filename,

int common_flag

);

The first parameter is the wildcard.

Wildcard examples :

- “*.*” – all files;

- “*.txt” – text files (to be read “files with a .txt extension”)

- “test.*” – files named test (any extension)

The FileFindFirst() function returns a search handler . The second parameter is the

first file that matches the search, and the third parameter is the location flag.

FileFindNext

The function resembles FileFindFirst() , just that the prototype is different:

1

2

bool FileFindNext(

long search_handle,

Page 8: MT4-5 Working With Files

MT4-5 Working with Files

8 | P a g e

3

4

string& returned_filename

);

The function resumes a previously started search with FileFindFirst() (it knows this

from the first parameter, search_handle). The function returns in the second

parameter the following file matching the wildcard. It returns true if it fills this

parameter with a valid file; if it fails to do that, and this happens at the end of the

search, it returns false.

FileFindClose

The function destroys a search handler.

Prototipul functiei este:

1

2

3

void FileFindClose(

long search_handle

);

It is necessary use the function in order to release the resources allocated by the call

of FileFindFirst().

The function prototypes and even names may be changed by MetaQuotes because at

moment this article is written the platform and the MetaEditor are still beta. If you

find any mistakes in the article please report.

Page 9: MT4-5 Working With Files

MT4-5 Working with Files

9 | P a g e

Working with files. Part II

January 28, 2010

By Bogdan Baltatu, MQLmagazine editor

[Versiunea romaneasca] [MQLmagazine.com in romana] [English edition]

This article continues the precedent article Working with files . Part I and it’s

intended to be it’s practical side.

The article shows in one code the use of the functions shown in Part I.

Before this, a few notes.

MetaQuotes changed the prototype of the FileOpen() function.

1

2

3

4

5

6

int FileOpen(

string file_name, // File name

int open_flags, // Combination of flags

short delimiter='\t' // Delimiter

uint codepage=CP_ACP // Code page

);

What was added is the codepage, that serves at the conversion of string variables.

Default is CP_ACP (Ansi Code Page).

To be known when using FileOpen(): if FILE_ANSI is not used, FILE_UNICODE is

presumed; even the end of the line is awaited as unicode (CRLF spanning 4 bytes

instead of 2).

Regarding the FileIsLineEnding() function, whose application seemed unclear in the

previous article, there is a small glitch to be known: indeed, function works only on

FILE_TXT files, and it answers true if the end of the line is reached by using

FileReadString(). Not by seeking. However, remember that most text files are ANSI.

Don’t forget to specify FILE_ANSI. Otherwise all readings will be abnormal,

including the fact that FileIsLineEnding() will not report correctly!

1

2

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

//| WorkWithFiles.mq5 |

Page 10: MT4-5 Working With Files

MT4-5 Working with Files

10 | P a g e

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

//| Copyright Baltatu Bogdan |

//| http:\\mqlmagazine.com |

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

#property copyright "Baltatu Bogdan"

#property link "http:\\mqlmagazine.com"

#property version "1.00"

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

//| Script program start function |

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

void OnStart()

{

int file_handle,size=-1,i;

bool res;

string svalue,filename;

long search;

//FileOpen

file_handle=FileOpen("test.txt",FILE_WRITE|FILE_TXT);

if(file_handle==-1) Print("FileOpen error.ErrorNo:",GetLastError());

else Print("FileOpen success!");

//FileIsExist

res=FileIsExist("test.txt");

if(res)Print("File exist!!");

else Print("File not found!!");

//FileWrite

svalue="abcdef\r\nghijkl";

size=StringLen(svalue);

FileWriteString(file_handle,svalue,size);

//FileFlush

FileFlush(file_handle);

//FileClose

FileClose(file_handle);

file_handle=FileOpen("test.txt",FILE_TXT|FILE_READ);

//FileTell

FileTell(file_handle);

Print("Cursor position:",FileTell(file_handle));

Page 11: MT4-5 Working With Files

MT4-5 Working with Files

11 | P a g e

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

//FileSeek

FileSeek(file_handle,0,SEEK_SET);

//FileClose

FileClose(file_handle);

//FileCopy

res=FileCopy("test.txt",0,"test1.txt",FILE_REWRITE);

if(res) Print("FileCopy Succes");

else Print("FileCopy Faild.ErrorNo:",GetLastError());

//FileMove

res=FileMove("test.txt",0,"move_test.txt",FILE_REWRITE);

if(res) Print("FileMove Succes!");

else Print("FileMove Faild!ErrorNo:",GetLastError());

//FileDelete

search=FileFindFirst("*.*",filename);

if(search!=INVALID_HANDLE)

{

Print("FileFindFirst returned",filename);

while(FileFindNext(search,filename))

{

i++;

Print(i,":",filename);

}

FileFindClose(filename);

}

else

Print("Files not found!!!");

FileDelete("test.txt");

}

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

Page 12: MT4-5 Working With Files

MT4-5 Working with Files

12 | P a g e

Working with files. Part III

February 28, 2010

By Bogdan Baltatu, MQLmagazine editor

[Versiunea romaneasca] [MQLmagazine.com in romana] [English edition]

This is the third article of the ‘Working with files’ series and I care to announce you

that this is one of the most important articles of the series because I’ll present the

writing functions as well as examples that will show some aspects of the functions.

The functions that refer strictly file writing are 8. These functions are:

1

2

FileWrite() , FileWriteArray() , FileWriteDouble() , FileWriteFloat() ,

FileWriteInteger() , FileWriteLong() , FileWriteString() ,

FileWriteStruct()

In the continuation I’ll present each function with its notes.

FileWrite()

The function is used for writing data in CSV files. The prototype of the function is:

1

2

3

4

uint FileWrite(

int file_handle // file handle

... // List of parameters to be written

);

The file_handle parameter represents the result of the FileOpen() function, that has

to be called with the flags FILE_CSV|FILE_WRITE. If the file is not open with the

FILE_WRITE flag, then FileWrite() will fail.

The parameter list to be written in the CSV file cannot be larger than 63, parameters

will be separated by the delimiter specified when we opened the file with the

FileOpen() function. Should we have not specify it at that time, the ‘tab’ delimiter

would have been default (ASCII 9).

The parameter type is not specified, they could be integer, datetime , float , … . It is

important to know that the FileWrite() function converts the parameters in strings.

Page 13: MT4-5 Working With Files

MT4-5 Working with Files

13 | P a g e

The double parameters have 16 digits after the decimal dot, the float parameters have

5, and the datetime parameters are converted to the ‘YYYY.MM.DD HH:MI:SS’.

Each FileWrite() command puts at the end of the generated string ‘\r\n’. This shows

us that after writing the string the cursor moves to the next row.

1

2

int file_handle=FileOpen("text.csv",FILE_ANSI|FILE_CSV|FILE_WRITE);

uint chars_written=FileWrite(file_handle,1,3,4,5,6,7);

In Excel 2007, even if delimiter is ‘tab’ and the parameters should be displayed on a

separate column they don’t show up. If we rename the file to ‘.txt’ and we open it with

Excel 2007 then parameters will be each on a column because it admits the ‘tab’

character. The issue is not with Excel and it deserves some study. It is recommended

to open the CSV with an editor as notepad or notepad++ if it has more than 65535

lines.

FileWriteArray()

The function writes elements of different types of array, except for the string ones, in

files opened as FILE_BIN.

The prototype of the function is:

1

2

3

4

5

6

int FileWriteArray(

int file_handle

void array[],

int start_item=0,

int items_count=WHOLE_ARRAY

);

The parameters of the function are file_handle , the result of the FileOpen(); array ,

the array that is source for the elements to be written in the file; start_item , position

in the array where to start writing from; items_count , the number of elements to be

copied starting from start_item.

The result of the FileWriteArray() function is the number of elements written in the

file, so the result of the function has to be equal to items_count for the function call

to be considered successfully.

Page 14: MT4-5 Working With Files

MT4-5 Working with Files

14 | P a g e

If the table has 9 elements and we send an items_count larger than 9, the

FileWriteArray() will not return any error, because it will write all the 9 elements.

Below you have a code example which writes a matrix in a binary file (opened with

FILE_BIN):

1

2

3

double array1[3][3]={{1.0, 2.0, 3.0}, {4.0, 5.0, 6.0}, {7.0, 8.0, 9.0}};

int file_handle=FileOpen("text.bin",FILE_BIN|FILE_WRITE);

int elements_written=FileWriteArray(file_handle,array1,0,WHOLE_ARRAY);

String arrays have to be written in TXT files. Each element, when written in the file,

is followed by the ‘\r\n’ characters, so each table element is written on a new line.

Below we exemplified in a code sample the functionality of FileWriteArray() if the

matrix is string.

1

2

3

string array1[3][3]={{"a", "b", "c"}, {"d", "e", "f"}, {"g", "h", "i"}};

int file_handle=FileOpen("text.txt",FILE_TXT|FILE_WRITE|FILE_ANSI);

int elements_written=FileWriteArray(file_handle,array1,6,3);

FileWriteDouble()

The function writes in a file from the current cursor position a value of the double

type. The function’s prototype is:

1

2

3

4

uint FileWriteDouble(

int file_handle

double dvalue

);

Parameters are two: file_handle is the file handle returned by FileOpen() and dvalue

is the double value that we wish to have it written in the file.

The function is considered successful if the result is 8, meaningly the length in bytes

of a double type variable, and the pointer moves by 8 bytes.

Below is a code example.

1 fh=FileOpen("test.bin",FILE_WRITE|FILE_BIN);

Page 15: MT4-5 Working With Files

MT4-5 Working with Files

15 | P a g e

2 s=FileWriteDouble(fh,a);

Warning: To use the FileWriteDouble() function, the file has to be opened binary,

otherwise the function fails.

FileWriteFloat()

The FileWriteFloat() function resembles FileWriteDouble() , only that the variable to

be written is of float type. The function’s prototype is:

1

2

3

4

uint FileWriteFloat(

int file_handle

float fvalue

);

The function parameters are file_handle , the reference of the file given by

FileOpen() and the float value that we wish to have it written in our file.

Code example.

1

2

fh=FileOpen("test.bin",FILE_WRITE|FILE_BIN);

s=FileWriteFloat(fh,a);

Of course, the result has to be 4, the length in bytes of a float type variable, for a

correct writing.

FileWriteInteger()

The function writes an integer typed variable in a binary file beginning from the

current pointer. The function's prototype is:

1

2

3

4

5

uint FileWriteInteger(

int file_handle

int ivalue,

int size=INT_VALUE

);

Page 16: MT4-5 Working With Files

MT4-5 Working with Files

16 | P a g e

The parameters of the function are : the file handle, the value that we wish to have

written, and its length in bytes.

The last parameter may be 1, 2 or 4 (1=char , 2=short, 4=integer).

The function returns 1,2 or 4 accordingly to the size parameter and the returned

value has to be equal with this, if the execution was correct.

Code example:

1

2

3

int a=2;

fh=FileOpen("test.bin",FILE_WRITE|FILE_BIN);

s=FileWriteInteger(fh,a,4);

The file has to be opened as binary, otherwise the function fails. If the function is

correctly executed then pointer moves with as much bytes as the function returns (1,

2 or 4).

We have to specify that by 'int' in the function's prototype the compiler actually

understands any integer type, and the function does not automatically presume

signed integers, being able to work with unsigned integers.

FileWriteLong()

The function writes a long typed value ion a binary file beginning with the current

cursor position in the file. The function's prototype is:

1

2

3

4

uint FileWriteLong(

int file_handle

long lvalue

);

The parameters of the function are : the file handle, returned by the FileOpen() call

and the value that we want to have written. If the function executes successfully, it

returns 8, the length in bytes of a long typed variable.

Code example

1

2

long a=212313123;

fh=FileOpen("test.bin",FILE_WRITE|FILE_BIN);

Page 17: MT4-5 Working With Files

MT4-5 Working with Files

17 | P a g e

3 s=FileWriteLong(fh,a);

FileWriteString()

The function writes a string in text or binary file beginning with the current position

of the cursor. The function's prototype is:

1

2

3

4

5

uint FileWriteString(

int file_handle

string svalue,

int size=-1

);

The parameters of the function are : the file handle, the string that we want to have

written, and the number of characters contained by the string.

The third parameter is mandatory if the file has been opened with FILE_BIN, but

optional when the file has been opened as FILE_TXT.

If the execution is successful then the result is the number of bytes written in the file

and the cursor's position moves by this number of bytes.

It should be noted that when we use the function to write in a FILE_UNICODE file

(specified or not, because FILE_UNICODE is default), the number of bytes written is

twice the number of characters. When we write with FILE_ANSI flag, the number of

bytes is the same as the number of characters. MetaQuotes' decision is a bit awkward

, to make FILE_UNICODE default instead of FILE_ANSI. It should be normal that

FILE_ANSI is default,

De precizat ar fi ca atunci cand folosim functia pentru a scrie intr-un fisier deschis cu

FILE_UNICODE (specificat sau nu, caci FILE_UNICODE e default) numarul de

bytes scrisi este de 2 ori mai mare decat numarul de caractere. Cand scriem cu flagul

FILE_ANSI numarul de bytes scrisi coincide cu numarul de caractere. E cel putin

ciudata decizia MetaQuotes sa faca FILE_UNICODE default in loc de FILE_ANSI.

Normal ar fi ca FILE_ANSI sa fie default, to avoid the useless doubling of the text

files, being known that the majority of users will open them with Notepad or Excel.

Code example.

Page 18: MT4-5 Working With Files

MT4-5 Working with Files

18 | P a g e

1

2

3

string a="A1b2C3";

fh=FileOpen("test.txt",FILE_WRITE|FILE_ANSI);

s=FileWriteString(fh,a);

FileWriteStruct()

The function writes in a binary typed file the contents of a structure parsed as

parameter beginning with the current cursor position. The prototype of the function

is:

1

2

3

4

5

uint FileWriteStruct(

int file_handle

any_simple_struct str_object&,

int size

);

The function parameters are : the file handle returned by FileOpen(), the structure

(by reference) and the length in bytes that has to be written. If the function is

executed successfully it returns the number of written bytes.

Code example:

1

2

3

4

5

MqlRates a[1];

CopyRates(Symbol(),PERIOD_D1,0,1,a);

int so=sizeof(a);

fh=FileOpen("te.bin",FILE_WRITE|FILE_BIN);

s=FileWriteStruct(fh,a,so);

When we define the structure 'a', we have to define it as array, to be able to use it

with the CopyRates() function, and it has to have at least one element.

It should be known that the files opened with FILE_BIN where we wrote something

will contain weird characters if opened. They are not wrongly written. Even if the

files are binary we saved them as '.txt' to be easily to be opened with the text editor

for you to see easier that something was written.

It seems that MetaQuotes has chosen a complicated path for files. I'll make a short

review on how Borland Pascal knew files, so you can see how simple was at that

Page 19: MT4-5 Working With Files

MT4-5 Working with Files

19 | P a g e

time (the '90s).

First, Borland Pascal didn't have the concept of file handle, a number to identify the

file. It had only file typed variables. These were complex variables, known only by

compiler - they couldn't have been read, written or interogated. The functions that

dealt with reading/writing were about 6 : ReadLn, WriteLn, Read, Write,

BlockRead, BlockWrite. ReadLn and WriteLn were working only with the screen,

keyboard and text files, while Read and Write were also working on the "binary"

level. Due to the special nature of the file variables, Read and Write knew from the

beginning if they have an I/O operation with keyboard/screen or with a file. There

was no need of FileRead or FileWrite, because if the first parameter was a file typed

variable, it couldn't have been mistaken with an integer or anything else - the

functions knew from beginning what they work with. If it was file of text , and you

were writing Write(f,128) , the function would have written "128", text, on 3

characters, and if the file would have been file of byte, the function would have

written a byte with the 128 value.

Also, the strict definition of variables made the difference between types and

functions knew from beginning how many bytes they had to read/write for any

data type. If file had a complex type , like file of record (record was the equivalent

for struct from MQL5), then functions were reading or writing one by one many

structures in a row, incrementing the cursor with the number of structures, not

with the number of bytes. BlockRead and BlockWrite were working with any kind

of variables, being interested only in the length of the read/written blocks (they

were working with untyped files).

Be careful when using file functions. Otherwise, you can lose time recording data that

are saved in a wrong manner!

Page 20: MT4-5 Working With Files

MT4-5 Working with Files

20 | P a g e

Working with files. Part IV

March 31, 2010

By Bogdan Baltatu, MQLmagazine editor

[Versiunea romaneasca] [MQLmagazine.com in romana] [English edition]

This article is the last from the ‘Working with files’ series and it will treat the file

reading functions exclusively. Functions that deal with file reading are :

1

2

FileReadArray(), FileReadBool(), FileReadDatetime(), FileReadDouble(),

FileReadFloat(),

FileReadInteger(), FileReadLong(), FileReadNumber(), FileReadString(),

FileReadStruct()

FileReadArray()

The function reads from a binary file arrays of any type except for string. The

function’s prototype is:

1

2

3

4

5

6

uint FileReadArray(

int file_handle // File handle

void array[], // Array to record

int start_item=0, // start array to write

int items_count=WHOLE_ARRAY // items count

);

The function parameters are : the file handle, the array being recorded in, the

position where reading begins and the number of elements to be read. The result is

the number of read elements.

Code example:

1

2

3

4

double b[];

int fh=FileOpen("test.bin",FILE_BIN|FILE_READ|FILE_WRITE);

FileWriteDouble(fh,5.123);

FileWriteDouble(fh,1.2123);

Page 21: MT4-5 Working With Files

MT4-5 Working with Files

21 | P a g e

5

6

7

FileSeek(fh,0,SEEK_SET);

FileReadArray(fh,b,0,WHOLE_ARRAY);

FileClose(fh);

I preferred to write in the binary file using the FileWriteDouble() function (lines 3

and 4) when I could have used the FileWriteArray() function, because I wanted you,

the reader, to play with the code and get the conclusion which I present here.

On the line 5 I called the function FileSeek() because If I would read immediately, the

cursor would be at the end of the file and function wouldn’t have read anything , so

before using the FileReadArray() you have to be sure the position of the cursor is in

the right place.

The type of the array must be the same with the type of the elements we wish to read.

If for instance we wrote in the file with FileWriteDouble(), the array where data must

get by FileReadArray() must be double. If it’s not, the data will be altered according

to the type of the b array ; in our case the function reads sets of 8 bytes each, because

a double spans over 8 bytes.

Write an element with FileWriteDouble() and one with FileWriteInteger() and make

the read in a double typed array to see what happens. After you do this you’ll draw

the conclusion that is better than in a file to keep only one type of function for writing

and the array or the structure where you read to be the same type as written

elements.

Be careful about the cursor’s position!

I remind you that the first element in an array is on the 0 position, so in our case the

first will be b[0] and the secondary will be b[1].

FileReadBool()

The function’s prototype is

1

2

3

bool FileReadBool(

int file_handle // File handle

);

Page 22: MT4-5 Working With Files

MT4-5 Working with Files

22 | P a g e

The function reads in a CSV typed file a string and converts to boolean.

Functia citeste dintr-un fisier CSV un string si il converteste in boolean; false for 0,

true for anything else.

FileReadDatetime()

The function reads from a CSV file a string in one of the formats: “YYYY.MM.DD

HH:MI:SS”, “YYYY.MM.DD” or “HH:MI:SS” and converts them in a datetime value.

The function’s prototype is:

1

2

3

4

5

6

7

8

9

10

11

12

13

datetime FileReadDatetime(

int file_handle

);

The function has just one parameter and that is the file handle

retrieved by FileOpen().

Code example.

<pre lang="mql5">int

fh=FileOpen("test.csv",FILE_CSV|FILE_READ|FILE_WRITE);

FileWrite(fh,"asd 12:54 06:00");

FileSeek(fh,0,SEEK_SET);

datetime dt=FileReadDatetime(fh);

FileClose(fh);

Note that on line 2 I wrote in the same string two substrings that can be interpreted

and converted as date (“12:54″ and “06:00″). The function reads always the first

string that can be converted to date from the current cursor position and converts it

in a variable of datetime type.

If our date is HH:MM then dt would take the value : “YYYY.MM.DD 12:54″ where

YYYY.MM.DD is the current date.

FileReadDouble()

The function reads a double from the current cursor position in a binary file. The

function’s prototype is:

Page 23: MT4-5 Working With Files

MT4-5 Working with Files

23 | P a g e

1

2

3

double FileReadDouble(

int file_handle

);

The function has a single parameter and that is the file handle returned by

FileOpen() and the function’s result is a double.

Code example:

1

2

3

4

5

6

int fh=FileOpen("test.bin",FILE_BIN|FILE_READ|FILE_WRITE);

FileWriteDouble(fh,1.1234);

FileWriteDouble(fh,0.0123);

FileSeek(fh,8,SEEK_SET);

double dvalue=FileReadDouble(fh);

FileClose(fh);

I wrote two double typed values in the file. If we ‘play’ with the second parameter of

the FileSeek() function, we will observe that the numbers differs from the typed one

because the function reads 8 bytes from the cursor position and the number returned

by FileReadDouble() will be different from the what’s written.

FileReadFloat()

The function reads a float from a binary file. The function’s prototype is:

1

2

3

float FileReadFloat(

int file_handle

);

The function has a single parameter and that is the file handle retrieved by

FileOpen().

Code example:

1

2

3

4

int fh=FileOpen("test.bin",FILE_BIN|FILE_READ|FILE_WRITE);

FileWriteFloat(fh,0.3f);

FileSeek(fh,0,SEEK_SET);

float fvalue=FileReadFloat(fh);

Page 24: MT4-5 Working With Files

MT4-5 Working with Files

24 | P a g e

5 FileClose(fh);

Same note as above: beware the cursor’s position!!

FileReadInteger()

The function reads and integer, short or char from the current pointer position

according to the specified bytes length. The function’s prototype is:

1

2

3

4

int FileReadInteger(

int file_handle // File handle

int size=INT_VALUE // Size of an integer in bytes

);

The function’s parameter are the file handle retrieved by FileOpen() and the number

of bytes to be read from the current cursor position. (1 for char, 2 for short, 4 for int).

Exemplu de cod:

1

2

3

4

5

int fh=FileOpen("test.bin",FILE_BIN|FILE_READ|FILE_WRITE);

FileWriteInteger(fh,15867,4);

FileSeek(fh,0,SEEK_SET);

int ivalue=FileReadInteger(fh,4);

FileClose(fh);

Even if I repeat myself one more time : beware at the cursor position and the number

of bytes to be read!

Chiar daca ma repet mai adaug o data : atentie la pozitia cursorului si atentie la

numarul de bytes pe care il citim.

FileReadLong()

The function reads a long integer (8 bytes) from the current position of a file opened

as binary. The function’s prototype is:

1

2

3

long FileReadLong(

int file_handle

);

Page 25: MT4-5 Working With Files

MT4-5 Working with Files

25 | P a g e

The function has only one parameter, the file handle returned by FileOpen().

Code example:

1

2

3

4

5

<pre lang="mql5"> int

fh=FileOpen("test.bin",FILE_BIN|FILE_READ|FILE_WRITE);

FileWriteInteger(fh,15867,8);

FileSeek(fh,0,SEEK_SET);

int ivalue=FileReadLong(fh);

FileClose(fh);

FileReadNumber()

The function reads from a CSV file a string from the current position until it finds the

separator then converts the string in a double.

The function’s prototype is:

1

2

3

double FileReadNumber(

int file_handle

);

The function has a single parameter and that is the file handle returned by

FileOpen().

Code example:

1

2

3

4

5

int fh=FileOpen("test.csv",FILE_CSV|FILE_READ|FILE_WRITE);

FileWrite(fh,1.2);

FileSeek(fh,0,SEEK_SET);

double dvalue=FileReadNumber(fh);

FileClose(fh);

If on line 2 we would have had “A”, then FileReadNumber() would have returned 0.

FileReadString()

The function reads from a string at the current position. The function has the

following prototype:

Page 26: MT4-5 Working With Files

MT4-5 Working with Files

26 | P a g e

1

2

3

4

string FileReadString(

int file_handle

int size=-1

);

The function has as parameters : file_handle, which is the returned by FileOpen()

and size which is the number of characters that we wish to read.

Code example:

1

2

3

4

int fh=FileOpen("test.bin",FILE_BIN|FILE_READ|FILE_WRITE);

FileWriteString(fh,"abcdef");

FileSeek(fh,0,SEEK_SET);

string svalue=FileReadString(fh,3);

If we open the file as text, the secondary parameter is not mandatory, because the

FileReadString() function will read until the end of the line marker (‘\r\n’). Also it’s

not mandatory for the case file is opened as CSV, because the function will read until

it finds the separator.

FileReadStruct()

The function reads the from a binary file into a structure, starting with the current

pointer position. The function’s prototype is:

1

2

3

4

5

uint FileReadStruct(

int file_handle //File handle

any_simple_struct str_object, // Structura that receives data

int size=-1 // Size of structure in bytes

);

Code example:

1

2

3

4

int fh=FileOpen("test.bin",FILE_BIN|FILE_READ|FILE_WRITE);

MqlRates w[1],r[1];

CopyRates(Symbol(),PERIOD_D1,0,1,w);

int so=sizeof(w[0]);

Page 27: MT4-5 Working With Files

MT4-5 Working with Files

27 | P a g e

5

6

7

8

uint s=FileWriteStruct(fh,w[0],so);

FileSeek(fh,0,SEEK_SET);

FileReadStruct(fh,r[0],so);

FileClose(fh);

I’d like to note that from MetaEditor build 252 the FileWriteStruct() and

FileReadStruct() functions work exclusively with structures, before that were

supporting arrays too. In older versions you could have written for instance

“FileWriteStruct(fh,a,so)” but now line is reported with error (“a – invalid access

array”).