Working with files. Part IV

[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
5
6
7
double b[];
int fh=FileOpen("test.bin",FILE_BIN|FILE_READ|FILE_WRITE);
FileWriteDouble(fh,5.123);
FileWriteDouble(fh,1.2123);
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
   );

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:

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
5
int fh=FileOpen("test.bin",FILE_BIN|FILE_READ|FILE_WRITE);
FileWriteFloat(fh,0.3f);
FileSeek(fh,0,SEEK_SET);
float fvalue=FileReadFloat(fh);
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    
);

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:

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 (‘rn’). 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
5
6
7
8
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]);
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”).

3 Responses to “ Working with files. Part IV ”

  1. Amir on April 3, 2010 at 11:05 pm

    Thanks for the site and article.
    When I write a txt file using FileWriteDouble, and trying to read
    it with FileReadDouble, should it be ok?
    At present I open the file for FILE_READ|FILE_TXT and get a good handle.
    but the FileReadDouble does not return any value.

    Is that the way to do it?

  2. Amir on April 4, 2010 at 12:29 am

    Ok, got it.
    It is the way, just misplaced something.

  3. Bogdan Caramalac, MQLmagazine sr.editor on April 4, 2010 at 9:05 am

    As I see it, the help doesn’t specifically say, at these functions, on which file types they work.
    However, the FileWriteDouble has it specified

    If successful the function returns the number of bytes written (in this case sizeof(double)=8). The file pointer is shifted by the same number of bytes.

    meaning that they work on binary files. For text files, easiest is to write them converted to strings, then read the strings and convert them to double.