– Cześć, Amigo! Wczoraj Raszi opowiedział Ci o FileInputStream i FileOutputStream. A dzisiaj opowiem Ci o klasach FileReader i FileWriter.

Jak już pewnie się domyślasz, wszystkie te klasy są adapterami pomiędzy obiektem File a «interfejsami» InputStream, OutputStream, Reader i Writer.

– Są one podobne do adapterów pomiędzy File a Reader/Writer, musisz tylko przekazać do konstruktora obiekt String, a nie File!

– Tak naprawdę, mają one kilka konstruktorów. Istnieją konstruktory zarówno dla obiektów File jak i String. Jeśli przekażesz obiekt String do konstruktora, wówczas konstruktor automatycznie utworzy obiekt File, używając ścieżki pliku pobranej z przekazanego obiektu String.

To dla ułatwienia. Projektanci Javy wybrali najczęstsze przypadki stosowania tych klas i napisali konstruktory dla wszystkich z nich. To całkiem wygodne, nie sądzisz?

– Och, naprawdę? Wygodne. Zgadzam się. Ale dlaczego muszę ciągle pisać:
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
– Dlaczego nie dodali tego przypadku zastosowania?

– Problem w tym, że  typowy program Java nie działa z konsolą. Szczerze mówiąc, prawie nigdy nic z niej nie odczytujesz. Nawet w przypadku serwera WWW, serwera aplikacji lub innego skomplikowanego systemu.

Ale mamy PrintStream do wysyłania danych i tekstu do konsoli. Ponieważ te «aplikacje serwerowe» często wykorzystują konsolę do wyświetlania swojego statusu, błędów i wszelkiego rodzaju innych informacji.

– Kumam. I można również kopiować pliki używając FileReader i FileWriter?

– Tak, o ile jest to plik tekstowy (tzn. składa się ze znaków). Oto przykład:

Skopiuj plik na dysk
public static void main(String[] args) throws Exception
{
 FileReader reader = new FileReader("c:/data.txt");
 FileWriter writer = new FileWriter("c:/result.txt");

 while (reader.ready()) //pod warunkiem, że w strumieniu wejściowym znajdują się nieodczytane bajty
 {
  int data = reader.read(); //Odczytaj jeden znak (char zostanie rozszerzony do int)
  writer.write(data); //Zapisz jeden znak (int zostanie obcięty/zawężony do char)
 }

 //Zamknij strumienie po zakończeniu korzystania z nich
 reader.close();
 writer.close();
}

– Prawie nie ma różnic.

– Tak, różnice są minimalne.