Fișiere

În memoria externă a calculatorului, datele se păstrează sub forma de fișiere. Fișierul (engleză: File) este o colecție de înregistrări situată, de regulă, pe un suport extern și identificată printr-un nume. Fiecare înregistrare (engleză: Record) este o grupare de informații sau de date care poate fi tratată în mod unitar.

Fișierele pot fi clasificate după diferite criterii.

După formatul înregistrărilor, distingem fișiere de text și fișiere de date.
    În fișierele de text, fiecare înregistrare este o linie de text, adică un șir de caractere care se termină cu un marcaj de trecere la linie nouă. Acest marcaj depinde de platformă. De exemplu, în fișierele MS-DOS marcajul de sfârșit de linie este format din secvența de caractere "\r\n", adică din caracterul de întoarcere la cap de linie (Carriage Return, '\r' ) și caracterul de linie nouă (New Line, '\n'), care au codurile ASCII 0x0D și respectiv 0x0A. Pe platforme Unix, marcajul de sfârșit de linie este constituit numai din caracterul '\n' (New Line, 0x0A). Liniile textului pot avea lungimi diferite. Codificarea caracterelor în fișier depinde, de asemenea, de platformă. În prezent, pentru fișierele de text se folosește cel mai frecvent codul ASCII, dar pot exista și platforme pe care se folosește Unicode sau o altă convenție de codificare.
    În fișierele de date, înregistrările au, de regulă, lungime predefinită, iar fiecare înregistrare este constituită din mai multe câmpuri de date. În principiu, toate înregistrările unui fișier de date au același format. Prin formatul înregistrării se înțelege descrierea structurii acesteia, care constă din specificarea câmpurilor de date pe care le conține, a lungimii fiecărui câmp, a tipului de date conținut în fiecare câmp și a modului de reprezentare a datelor. Datele din câmpuri pot fi  reprezentate fie sub forma lor externă, fie sub formă binară, iar formatul înregistrărilor diferă de la un fișier la altul.

După modul de exploatare, fișierele pot fi de intrare, de ieșire sau de intrare/ieșire (de manevră). În cazul fișierelor de intrare, din momentul deschiderii fișierului și până în momentul închiderii acestuia se pot efectua numai operații de citire. În cazul fișierelor de ieșire, între momentele de deschidere și de închidere a fișierului respectiv se pot face numai operații de scrieire. Desigur însă că, după ce s-a încheiat scrierea într-un anumit fișier de ieșire și acesta a fost închis, el poate fi deschis ca fișier de intrare. Același fișier poate fi citit de mai multe ori. Fișierele de intrare/ieșire permit ca, după ce au fost deschise, să se efectueze atât operații de scriere, cât și de citire.

După modul de acces fișierele pot fi cu acces secvențial sau cu acces direct. Fișierele cu acces secvențial se caracterizează prin faptul că înregistrările lor pot fi parcurse într-un singur sens, în ordinea în care acestea sunt plasate în fișier. În cazul fișierelor cu acces direct, numite și fișiere cu acces aleator (engleză: random access file) ordinea de parcurgere a înregistrărilor din fișier este arbitrară, în sensul că la fiecare operație de intrare/ieșire făcută asupra fisierului respectiv se poate indica adresa sau numărul de ordine al înregistrării care va fi citită sau scrisă.

În limbajul Java, fișierul este privit ca sursa sau destinația unui flux. În cazul citirii din fișier, datele se transmit de la acesta către memoria internă sub forma unui flux de intrare. În cazul operației de scriere, datele se transmit de la memoria internă la fișier sub forma unui flux de ieșire.

În principiu, comunicarea între memoria internă și un fișier de text se face sub forma unui flux de caractere. Totuși, pe platformele pe care reprezentarea caracterelor se face pe un octet (de exemplu în cod ASCII), acesta poate fi tratat și ca un flux de octeți.

În cazul fișierelor de date, comunicarea dintre memoria internă și fișier se poate face prin fluxuri de caractere numai dacă datele din fișier sunt reprezentate exclusiv în format extern (deci sub forma de șiruri de caractere). Dacă însă există și câmpuri de date în format binar, legatura dintre memoria internă și fișierul de date se face, de regula, prin fluxuri de octeți.

Operațiile cu fișierul se fac în ordinea următoare:
    1/ se deschide fișierul, în care scop trebuie să se comunice sistemului de operare numele fișierului, locul în care se găsește (de exemplu unitatea de disc și calea către directorul care îl conține) și modul în care va fi utilizat (pentru citire, pentru scriere sau în ambele moduri);
    2/ se exploatează fișierul, efectuând o succesiune de operații de citire/scriere;
    3/ se închide fișierul.

În limbajul Java, se consideră că, în operațiile de intrare/ieșire, între fișier și memorie se transmit numai fluxuri de caractere sau de octeți, fară să se ia în considerație informația pe care o conțin aceste fluxuri. Întreaga responsabilitate privind interpretareaacestor fluxuri revine programelor care le prelucrează.

Clasa File

Instanțele clasei java.io.File conțin informații privind numele fișierului și calea pe care se găseste acesta (engleza: Path). Clasa File oferă, de asemenea, metode prin care se pot face unele operații legate de prezența fișierului respectiv: se poate afla dacă fișierul există, dacă el poate fi citit sau scris, se poate crea un fișier nou, se poate șterge un fișier existent etc.
 
Calea indică modul în care poate fi localizat fișierul de pe disc. Calea poate fi absolută sau relativă. Calea absolută constă în indicarea unității de disc și a succesiunii de directoare prin care se ajunge de la rădacină la  fișierul care ne interesează. Calea relativă, arată cum se poate ajunge de la directorul curent la fișierul căutat.

Se știe că, pe diferite platforme, calea se reprezintă în moduri diferite. De exemplu, în sistemul Unix, calea relativa "../../alpha/beta/fisier1.txt"  indică faptul că, pornind de la directorul curent, se face o deplasare către rădăcină cu doua directoare, după care se merge înainte (către frunzele arborelui director) trecând la subdirectorul alpha și de aici la subdirectorul beta, în care se găsește fișierul căutat cu numele fișier1.txt. Remarcăm că separarea directoarelor se face prin caracterul '/' (slash). Pe platformele firmei Microsoft (MS-DOS, Windows), ca separator se folosește caracterul '\'  (backslash), care în limbajele C și Java se reprezintă sub forma '\\'. În consecință, aceeași cale relativă se va scrie pe o astfel de platforma sub forma "..\\..\\alpha\\beta\\fisier1.txt".

În clasa File, reprezentarea căii se face sub o formă independentă de platformă. În acest scop, în instanțele clasei File, calea se păstrează sub forma unui tablou de șiruri de caractere, în care se memoreaza numele fiecărui director conținut în cale. Separatorul se păstrează într-un câmp separat și este setat automat în funcție de sistemul de operare al calculatorului pe care se execută programul. În acest fel, portabilitatea programului crește, întrucât nu trebuie modificate căile fișierelor folosite în program atunci când se trece de pe o platformă pe alta.

ATENȚIE: pentru asigurarea portabilității programelor sursă, este recomandabil ca, în căile date ca argumente ale metodelor clasei File, să se folosească numai varianta Unix de separatori. Compilatorul javac de pe platformele Microsoft înlocuiește automat separatorul '/' prin ' \\' in timp ce pe platformele Unix (Linux) nu se face înlocuirea inversă.

Remarcăm că numele clasei File poate să ne inducă în eroare, lăsându-ne să credem că instanțele acestei clase sunt fișiere. În realitate, instanțele ei conțin căile și numele fișierelor.
 

Clasa File prezentată în detaliu

Câmpuri:
    public static final char separatorChar - conține caracterul prin care se separă directoarele dintr-o cale; acest carecter este dependent de platforma, fiind '/' (slash) pe platforme Unix și '\' (backslash) pe platforme Microsoft;
    public static final String separator - conține caracterul de separare (separatorChar) sub forma de String;
    public static final char pathSeparatorChar - conține caracterul de separare a căilor; acest caracter este dependent de platformă, fiind ':' (două puncte) sub Unix și ';' (punct și virgulă) pe platforme Microsoft;
    public static final String pathSeparator - caracterul de separare a căilor (pathSeparatorChar) sub formă de String.
NOTĂ: aceste câmpuri se completează automat, în funcție de platforma pe care rulează programul.

Constructori:
    public File(String pathname) - creează o instanță a clasei File, care conține calea dată ca argument;
    public File(String parent, String child) - creează o instanță a clasei File, în care calea este compusă dintr-o cale "părinte" (formată numai din directoare) și o cale "copil" (care poate fi director sau fișier);
    public File(File parent, String child) - se deosebește de constructorul precedent numai prin faptul că "părintele" este o instanță a clasei File.

Metode:
Specificăm aici principalele metode ale clasei File.
    public String getName() - întoarce numele fișierului (ultimul nume din cale); dacă această cale este vidă, întoarce un șir vid;
    public String getParent() - întoarce calea părinte;
    public File getParentFile() - întoarce calea părinte sub forma de instanță a clasei File;
    public String getPath() - întoarce calea conținută în această instanță; calea va conține separatorii impliciți de pe platforma curentă;
    public boolean isAbsolute() - intoarce true dacă această cale este absolută (dacă este prefixată cu '/' pe platformele Unix sau cu '\\' pe platformele Microsoft);
    public String getAbsolutePath() - întoarce calea absolută corespunzătoare căii conținute în această instanță;
    public File getAbsoluteFile() - întoarce o instanță a clasei File care conține calea absolută corespunzatoare celei din instanța curentă;
    public URL toURL() - întoarce un URL (Uniform Resource Locator) corespunzător căii din această instanță; forma acestui URL este dependentă de sistem (Nota: URL-ul se folosește pentru a localiza un fișier cu ajutorul unui browser de Web);
    public boolean canRead() - testează dacă aplicația poate citi fișierul indicat de această instanță a clasei File;
    public boolean canWrite() - testează dacă aplicația poate scrie în fișierul indicat;
    public boolean exists() - testează dacă fișierul indicat există;
    public boolean isDirectory() - testează dacă ultimul nume din această cale este al unui director;
    public boolean isFile() - testează dacă ultimul nume din această cale este al unui fișier;
    public long lastModified() - întoarce timpul la care s-a făcut ultima modificare în fișierul indicat de această cale (exprimat în milisecunde de la 1 ianuarie 1970 ora 00:00:00 GMT);
    public long length() - întoarce lungimea fișierului indicat de această instanță (în octeți);
    public boolean createNewFile() throws IOException - dacă fișierul indicat în această cale nu există, creează un fișier nou vid;
    public boolean delete() - șterge fișierul; întoarce truedacă ștergerea a avut loc;
    public void deleteOnExit() - cere ca fișierul să fie șters când se încheie funcționarea mașinii virtuale Java (are efect numai dacă funcționarea se încheie normal);
    public String[] list() - întoarce un tablou de șiruri, care conține numele de directoare și de fișier din această cale;
    public File[] listFile() - dacă această cale nu se încheie cu un nume de director, întoarce null; altfel întoarce un tablou de instanțe ale clasei File, câte una pentru fiecare nume de fișier din directorul indicat de această cale.

Exemplu:
În fișierul TestFile.java este dat un exemplu de aplicație, în care se testează utilizarea metodelor clasei File. Metodele se aplică pentru un fișier situat în directorul curent, pentru un director și pentru un fișier situat în alt director.



© Copyright 2000 - Severin BUMBARU, Universitatea "Dunărea de Jos" din Galați