Lucrul cu fisiere. Partea a IV-a
[English version] [MQLmagazine.com in english] [Editia romaneasca]
Acesta este ultimul articol din seria ‘Lucrul cu fisiere’ si el va trata exclusiv functiile de citire din din fisiere. Functiile care se ocupa cu citirea din fisiere sunt :
1 2 | FileReadArray(), FileReadBool(), FileReadDatetime(), FileReadDouble(), FileReadFloat(), FileReadInteger(), FileReadLong(), FileReadNumber(), FileReadString(), FileReadStruct() |
FileReadArray()
Functia citeste dintr-un fisier BIN tablouri de orice tip cu exceptia string. Prototipul functiei este:
1 2 3 4 5 6 | uint FileReadArray( int file_handle // Referinta fisierului void array[], // Tabloul in care citim int start_item=0, // Pozitia de la care se incepe citirea int items_count=WHOLE_ARRAY // Numarul de elemente pe care vrem sa il citim ); |
Parametrii functiei sunt : referinta fisierului, tabloul in care citim, pozitia de unde incep citirea si numarul de elemente care vreau sa fie citit. Rezultatul functiei este numarul de elemente citite.
Exemplu de cod:
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); |
Am preferat sa scriu in fisierul bin folosindu-ma de FileWriteDouble() (liniile 3 si 4) cand puteam folosi FileWriteArray() , deoarece am vrut ca tu , cititorule sa poti sa te joci cu codul si sa poti sa tragi concluziile pe care ti le voi expune.
Pe linia 5 am apelat functia FileSeek() deoarece daca faceam imediat citirea cursorul era la sfarsitul fisierului si functia nu ar mai fi citit nici un element nemaiavand ce sa mai citeasca , asadar inainte de a folosi functia FileReadArray() asigurati-va ca pozitia cursorului este in locul dorit.
Tipul tabloului trebuie sa coincida cu tipul elementelor pe care dorim sa le citim. De exemplu daca am scris in fisier cu FileWriteDouble() , tabloul in care in ajung datele citite cu FileReadArray() trebuie sa fie de tip double. Daca nu este, datele vor fi alterate in functie de tipul matricei b ; in cazul nostru functia citeste seturi de cate 8 bytes , deoarece un numar double se scrie pe 8 bytes.
Scrieti un element cu FileWriteDouble() si unul cu FileWriteInteger() si faceti citirea intr-un tablou de tip double sa vedeti ce se intampla. Dupa ce o sa faceti asta o sa ajungeti la concluzia ca este mai bine intr-un fisier sa folositi un singur fel de functie pentru scriere si tabloul sau structura in care faceti citirea sa fie de acelasi tip cu elementele scrise.
Mare atentie la pozitia cursorului!!
Va readuc aminte ca intr-un tablou primul element se gaseste pe pozitia 0 , deci in cazul nostru primul element o sa fie b[0] si al doilea b[1].
FileReadBool()
Prototipul functiei este:
1 2 3 | bool FileReadBool( int file_handle // Referinta fisierului ); |
Functia citeste dintr-un fisier CSV un string si il converteste in boolean; false daca citeste 0, true pentru orice altceva.
FileReadDatetime()
Functia citeste dintr-un fisier CSV un string in unul din formatele: “YYYY.MM.DD HH:MI:SS”, “YYYY.MM.DD” sau “HH:MI:SS” si le converteste intr-o valoare de tip datetime. Prototipul functiei este:
1 2 3 4 5 6 7 8 9 10 11 12 13 | datetime FileReadDatetime( int file_handle // Referinta fisierului ); Functia are un singur parametru si anume referinta fisierului data de functia FileOpen(). Exemplu de cod: <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); |
Observati pe linia 2 ca am scris in acelasi string doua substringuri care pot fi interpretate si convertite ca data (“12:54″ si “06:00″).Functia citeste intotdeaua primul string care poate fi convertit in data de la pozitia curenta a cursorului si il converteste intr-o variabila de tip data.
Daca data noastra este de forma HH:MM atunci dt va lua valoarea : “YYYY.MM.DD 12:54″ , unde YYYY.MM.DD este data curenta.
FileReadDouble()
Functia citeste un numar de tip double dintr-un fisier BIN de la pozitia curenta a cursorului. Prototipul functiei este:
1 2 3 | double FileReadDouble( int file_handle // Referinta fisierului ); |
Functia are un singur parametru si anume referinta fisierului intoarsa de FileOpen() si rezultatul functiei este un numar de tip Double.
Exemplu de cod:
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); |
Am scris doua valori de tip double in fisier.Daca ne ‘jucam’ cu al doilea parametru al functiei FileSeek() o sa observam ca numarul difera de cel introdus deoarece functia citeste 8 bytes de la pozitia cursorului si numarul intors de functia FileReadDouble() va fi diferit de ce scris.
FileReadFloat()
Functia citeste un numar float dintr-un fisier BIN. Prototipul functiei este:
1 2 3 | float FileReadFloat( int file_handle // Referinta fisierului ); |
Functia are un singur parametru si anume referinta fisierului data de functia FileOpen().
Exemplu de cod:
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); |
Aceleasi precizari ca la functiile de mai sus: atentie la pozitia cursorului!!
FileReadInteger()
Functia citeste un integer , short sau char de la pozitia curenta a pointerului in functie la lungimea in bytes specificata. Prototipul functiei este:
1 2 3 4 | int FileReadInteger( int file_handle // Referinta fisierului int size=INT_VALUE // Marimea unui intreg in bytes ); |
Parametrii functiei sunt referinta fisierului intoarsa de FileOpen() si numarul de bytes care pe care o sa il citim de la pozitia curenta a cursorului. (1 pentru char , 2 pentru short , 4 pentru 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); |
Chiar daca ma repet mai adaug o data : atentie la pozitia cursorului si atentie la numarul de bytes pe care il citesti!
FileReadLong()
Functia citeste un intreg de tip long (8 bytes) de la pozitia curenta a unui fisier deschis ca BIN. Prototipul functiei este:
1 2 3 | long FileReadLong( int file_handle // Referinta fisierului ); |
Parametrul functiei este referinta fisierului intors de functia FileOpen().
Exemplu de cod:
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()
Functia citeste dintr-un CSV un string de la pozitia curenta pana cand se intalneste separatorul si converteste string-ul intr-un double. Prototipul functiei este:
1 2 3 | double FileReadNumber( int file_handle // Referinta fisierului. ); |
Functia are un singur parametru si anume referinta fisierului intoarsa de functia FileOpen().
Exemplu de cod:
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); |
Daca pe linia 2 scriam in loc de 1.2 scria “A” atunci functia FileReadNumber ar fi intors 0.
FileReadString()
Functia citeste dintr-un string de la pozitia curenta. Prototipul functiei este :
1 2 3 4 | string FileReadString( int file_handle // Referinta fisierului int size=-1 // Lungimea stringului ); |
Functia are ca parametri : file_handle , care este referinta fisierului intoarsa de FileOpen si size care este numarul de caractere pe care dorim sa il citim.
Exemplu de cod:
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); |
Daca deschidem fisierul ca text , al doilea parametru nu este necesar , functia FileReadString() va citi pana va intalni sfarsitul de linie (‘\r\n’). Nici in cazul fisierelor deschise ca CSV al doilea parametru nu este necesar , functia citeste intalneste separatorul.
FileReadStruct()
Functia citeste continutul intr-o structura dintr-un fisier BIN , incepand cu pozitia curenta a pointerului. Prototipul functiei este:
1 2 3 4 5 | uint FileReadStruct( int file_handle // Referinta fisierului any_simple_struct str_object, // Structura in care fac citirea int size=-1 // Marimea structurii in bytes ); |
Exemplu de cod:
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); |
As vrea sa precizez ca de la versiunea 252 a MetaEditor in FileWriteStruct() si FileReadStruct() lucreaza strict cu structuri, iar inainte lucrau si cu tablouri. In versiunile mai vechi mergea sa scriem de exemplu “FileWriteStruct(fh,a,so)” dar acum linia se intoarce cu eroare (“a – invalid access array”).