Citirea și scrierea fișierelor - FileInputStream și FileOutputStream
Scrierea fișierelor și clasa FileOutputStream
Clasa FileOutputStream este destinată scrierii de octeți în fișier. Aceasta derivă din clasa OutputStream, deci moștenește toată funcționalitatea acesteia.
Prin constructorul clasei FileOutputStream se specifică fișierul în care se va face scrierea. Clasa suportă mai mulți constructori:
FileOutputStream(String filePath)
FileOutputStream(File fileObj)
FileOutputStream(String filePath, boolean append)
FileOutputStream(File fileObj, boolean append)
Fișierul este specificat fie prin calea sub formă de șir de caractere, fie printr-un obiect File. Al doilea parametru - append determină modul de scriere: dacă este true, datele sunt adăugate la sfârșitul fișierului, iar dacă este false, fișierul este rescris complet.
De exemplu, să scriem un șir într-un fișier:
import java.io.*;
public class Program {
public static void main(String[] args) {
String text = "Hello world!"; // șir pentru scriere
try(FileOutputStream fos=new FileOutputStream("notes.txt"))
{
// convertirea șirului în octeți
byte[] buffer = text.getBytes();
fos.write(buffer, 0, buffer.length);
System.out.println("The file has been written");
}
catch(IOException ex){
System.out.println(ex.getMessage());
}
}
}
Pentru a crea un obiect FileOutputStream, se folosește constructorul care primește calea către fișierul în care se va face scrierea. Dacă fișierul nu există, acesta este creat automat la scriere. Deoarece scriem un șir, acesta trebuie mai întâi convertit într-un tablou de octeți. Cu ajutorul metodei write, șirul este scris în fișier.
Pentru închiderea automată a fișierului și eliberarea resurselor, obiectul FileOutputStream este creat folosind construcția try...catch.
Nu este necesar să scriem întregul tablou de octeți. Folosind suprascrierea metodei write(), putem scrie și un singur octet:
fos.write(buffer[0]); // scrierea primului octet
Citirea fișierelor și clasa FileInputStream
Pentru citirea datelor din fișier, se utilizează clasa FileInputStream, care este moștenită din clasa InputStream și implementează toate metodele acesteia.
Pentru a crea un obiect FileInputStream, putem folosi mai mulți constructori. Cea mai utilizată versiune a constructorului primește ca parametru calea către fișierul care trebuie citit:
FileInputStream(String fileName) throws FileNotFoundException
Dacă fișierul nu poate fi deschis, de exemplu, nu există la calea specificată, se generează o excepție FileNotFoundException.
Să citim datele dintr-un fișier deja scris și să le afișăm în consolă:
import java.io.*;
public class Program {
public static void main(String[] args) {
try(FileInputStream fin=new FileInputStream("notes.txt"))
{
int i;
while((i=fin.read())!=-1){
System.out.print((char)i);
}
}
catch(IOException ex){
System.out.println(ex.getMessage());
}
}
}
În acest caz, citim fiecare octet separat în variabila i:
while((i=fin.read())!=-1){
Când nu mai sunt date disponibile pentru citire, metoda returnează valoarea -1.
Fiecare octet citit este apoi convertit într-un obiect de tip char și afișat în consolă.
În mod similar, putem citi datele într-un tablou de octeți și să le manipulăm ulterior:
import java.io.*;
public class Program {
public static void main(String[] args) {
try(FileInputStream fin=new FileInputStream("notes.txt"))
{
byte[] buffer = new byte[256];
System.out.println("File data:");
int count;
while((count=fin.read(buffer))!=-1){
for(int i=0; i<count;i++){
System.out.print((char)buffer[i]);
}
}
}
catch(IOException ex){
System.out.println(ex.getMessage());
}
}
}
În acest caz, cu ajutorul metodei read() citim datele în tabloul buffer de 256 octeți. Metoda returnează numărul de octeți citiți.
Fiindcă fișierul poate avea mai mult de 256 octeți, citim în ciclu while până la sfârșitul fișierului. Când nu mai rămân fișiere de citit, metoda returnează -1.
while((count=fin.read(buffer))!=-1){
Deoarece numărul de octeți citiți/dimensiunea fișierului poate fi mai mic decât 256 octeți, numărul real de octeți citiți este stocat în variabila count. Apoi, afișăm datele citite în consolă într-un ciclu for.
for(int i=0; i<count;i++){
System.out.print((char)buffer[i]);
}
Să combinăm ambele clase și să facem citirea dintr-un fișier și scrierea în altul:
import java.io.*;
public class Program {
public static void main(String[] args) {
try(FileInputStream fin=new FileInputStream("notes.txt");
FileOutputStream fos=new FileOutputStream("notes_new.txt"))
{
byte[] buffer = new byte[256];
int count;
// citim în buffer
while((count=fin.read(buffer))!=-1){
// scriem din buffer în fișier
fos.write(buffer, 0, count);
}
System.out.println("File has been written");
}
catch(IOException ex){
System.out.println(ex.getMessage());
}
}
}
Clasele FileInputStream și FileOutputStream sunt destinate în principal pentru scrierea fișierelor binare, adică pentru scrierea și citirea octeților. Deși pot fi utilizate și pentru lucrul cu fișiere text, totuși, pentru această sarcină sunt mai potrivite alte clase.