Programowanie Obiektowe (Java)

Podobne dokumenty
Biblioteki wejścia/wyjścia. Strumienie we/wy (I/O)

Strumienie i serializacja

Wykład 4: Wejście/wyjście: strumienie Java

Kurs programowania. Wykład 10. Wojciech Macyna. 05 maja 2016

JAVA. Strumienie wejścia i wyjścia. Pliki - zapis i odczyt

STRUMIENIE DANYCH, SERIALIZACJA OBIEKTÓW

Język JAVA podstawy. Wykład 6, część 2. Jacek Rumiński. Politechnika Gdańska, Inżynieria Biomedyczna

Programowanie Obiektowe (Java)

Rozdział 7 Strumienie, operacje wejścia-wyjścia

Strumienie, pliki. Sortowanie. Wyjątki.

Podstawy otwartych języków programowania Wyjątki i strumienie I/O

dr Krzysztof Podlaski

Java niezbędnik programisty spotkanie nr 11. Importy statyczne, wejście/wyjście, wyrażenia regularne, serializacja

Podstawy i języki programowania

Programowanie w języku Java WYKŁAD

Wstęp do Java. Operacje Wejścia-Wyjścia Programowanie Wielowątkowe. dr Krzysztof Podlaski. Wydział Fizyki i Informatyki Stosowanej

Java Zadanie 1. Aby poprawnie uruchomić aplikację desktopową, należy zaimplementować główną metodę zapewniającą punkt wejścia do programu.

Wykład 10: Wejście i Wyjście

Przygotował: Jacek Sroka 1. Java SE. Strumienie

STRUMIENIE TEKSTOWE WEJŚCIOWE WPROWADZANIE DANYCH STRUMIENIE BAJTOWE, STRUMIENIE TEKSTOWE

Wykład 2: Podstawy Języka

1 Klasa File. 2 Writer. Programowanie w j zyku Java - Adam Krechowicz. Klasa File zapewnia podstawowe operacje na plikach

Platformy Programistyczne Zagadnienia sieciowe i wątki

Programowanie obiektowe

Język JAVA podstawy. wykład 2, część 1. Jacek Rumiński. Politechnika Gdańska, Inżynieria Biomedyczna

Strumienie, pliki. Sortowanie. Wyjątki.

Programowanie obiektowe

Inynieria oprogramowania Lecture XXX. Java TM cz IV: IO. Bartosz Walter

Aplikacje RMI. Budowa aplikacji rozproszonych. Część 2.

Programowanie obiektowe

Programowanie obiektowe

Obszar statyczny dane dostępne w dowolnym momencie podczas pracy programu (wprowadzone słowem kluczowym static),

Języki i metody programowania Java INF302W Wykład 4

KOMUNIKACJA MIĘDZYPROCESOWA O B S Ł U G A WEJŚCIA/WYJŚCIA

Programowanie proceduralne INP001210WL rok akademicki 2018/19 semestr letni. Wykład 6. Karol Tarnowski A-1 p.

MATERIAŁY POMOCNICZE DO ĆWICZENIA 3 Klasy i obiekty; atrybuty i metody

Informatyka I. Klasy i obiekty. Podstawy programowania obiektowego. dr inż. Andrzej Czerepicki. Politechnika Warszawska Wydział Transportu 2018

Programowanie obiektowe

Podstawy Języka Java

K O M U N I K A C J A MIĘDZYPROCESOWA O B S Ł U G A WEJŚCIA/WYJŚCIA

Programowanie obiektowe zastosowanie języka Java SE

Języki i metody programowania Java INF302W Wykład 3 (część 1)

Podstawy obiektowości

Programowanie obiektowe

Programowanie obiektowe. Literatura: Autor: dr inŝ. Zofia Kruczkiewicz

Język JAVA podstawy. Wykład 6, część 1. Jacek Rumiński. Politechnika Gdańska, Inżynieria Biomedyczna

Klasy. dr Anna Łazińska, WMiI UŁ Podstawy języka Java 1 / 13

Wykład 4: Klasy i Metody

JAVA I SIECI. MATERIAŁY:

PARADYGMATY PROGRAMOWANIA Wykład 4

Dokumentacja do API Javy.

Java - tablice, konstruktory, dziedziczenie i hermetyzacja

Java. język programowania obiektowego. Programowanie w językach wysokiego poziomu. mgr inż. Anna Wawszczak

Programowanie w Internecie. Java

Wstęp do programowania INP001213Wcl rok akademicki 2017/18 semestr zimowy. Wykład 12. Karol Tarnowski A-1 p.

Podstawowe części projektu w Javie

System obsªugi wej±cia i wyj±cia.

Wykład 8: Obsługa Wyjątków

Katalog książek cz. 2

Techniki programowania INP001002Wl rok akademicki 2018/19 semestr letni. Wykład 3. Karol Tarnowski A-1 p.

Programowanie obiektowe

Kurs programowania. Wykład 2. Wojciech Macyna. 17 marca 2016

Języki i Techniki Programowania II. Wykład 6. Wejście/Wyjście

Programowanie w Javie Lista nr 1. Wybieramy kategorię Java, a wśród Projektów Java Application i [NEXT]

Interfejsy. Programowanie obiektowe. Paweł Rogaliński Instytut Informatyki, Automatyki i Robotyki Politechniki Wrocławskiej

Rozdział 4 KLASY, OBIEKTY, METODY

Aplikacje w środowisku Java

Aplikacja wielowątkowa prosty komunikator

Programowanie obiektowe

Współbieżność i równoległość w środowiskach obiektowych. Krzysztof Banaś Obliczenia równoległe 1

Bezpieczne uruchamianie apletów wg

Wykład 4. Tablice. Pliki

Wykład 7: Pakiety i Interfejsy

JAVA W SUPER EXPRESOWEJ PIGUŁCE

Wprowadzanie danych z klawiatury. Wyjątki związane z wprowadzaniem danych, przekroczeniem rozmiaru tablicy, dzieleniem przez zero itd.

Techniki programowania INP001002Wl rok akademicki 2017/18 semestr letni. Wykład 5. Karol Tarnowski A-1 p.

Kurs programowania. Wykład 9. Wojciech Macyna. 28 kwiecień 2016

Wykład 2. Strumienie tekstowe (wprowadzanie danych z klawiatury) i bajtowe, otwieranie strumieni poprzez sieć - obiekty URL

Obiektowe programowanie rozproszone Java RMI. Krzysztof Banaś Systemy rozproszone 1

WSNHiD, Programowanie 2, Lab. 3. Trwałość danych

Programowanie w języku Java (OCA+OCP)

Podstawy otwartych języków programowania Przechowywanie danych

Multimedia JAVA. Historia

KLASY, INTERFEJSY, ITP

Korzystanie z bibliotek standardowych

Java Język programowania

Aplikacje w środowisku Java

Aplikacja wielow tkowa prosty komunikator

Informatyka I. Typy danych. Operacje arytmetyczne. Konwersje typów. Zmienne. Wczytywanie danych z klawiatury. dr hab. inż. Andrzej Czerepicki

Zaawansowane techniki programowania C#

Programowanie Obiektowe Java

Interfejsy i klasy wewnętrzne

Sposoby tworzenia projektu zawierającego aplet w środowisku NetBeans. Metody zabezpieczenia komputera użytkownika przed działaniem apletu.

Prototype (prototyp) Cel: Przykład: Określenie rodzaju tworzonych obiektów poprzez wskazanie ich prototypu. Nowe instancje tworzymy kopiując prototyp.

Konstruktory. Streszczenie Celem wykładu jest zaprezentowanie konstruktorów w Javie, syntaktyki oraz zalet ich stosowania. Czas wykładu 45 minut.

Programowanie obiektowe

JAVA. Java jest wszechstronnym językiem programowania, zorientowanym. apletów oraz samodzielnych aplikacji.

Podejście obiektowe. Tablice obiektów Przykład 1 metody i atrybuty statyczne oraz niestatyczne

Język JAVA podstawy. Wykład 3, część 3. Jacek Rumiński. Politechnika Gdańska, Inżynieria Biomedyczna

Języki i metody programowania Java INF302W Wykład 2 (część 1)

Transkrypt:

1. Kontenery w Javie 5 Wykład dziewiąty 1 import java.util.*; 2 3 class Element { 4 private int value; 5 6 public String tostring() { 7 return new Integer(value).toString(); 8 } 9 10 public Element(int x) { 11 value=x; 12 } 13 } 14 15 public class Listy { 16 public static void main(string[] args) { 17 ArrayList<Element> a = new ArrayList<Element>(); 18 LinkedList<Element> l = new LinkedList<Element>(); 19 Iterator<Element> it; 20 21 for(int i=0;i<20; i++) 22 a.add(new Element((int)(Math.random()*20))); Jednym z nowych elementów jakie zostały dodane do języka Java w jej najnowszym wydaniu (numer środowiska 1.5) s ą typy ogólne ( ang. generics), które wzbogacaj ą język Java o mechanizmu podobny do mechanizmu szablonów, znanego z języka C++. S ą one stosowane między innymi w kontenerach. Dzięki nim możemy określi ć jakiej klasy obiekty będ ą przechowywane w kontenerze (lub jaki interfejs będą implementowały te obiekty). Dzięki temu możemy częściowo ograniczyć rzutowanie w dół 1, które nie jest bezpieczne, jeśli nie stosujemy żadnego mechanizmu rozpoznawania typu podczas wykonania programu. Nie możemy jednak, stosując typy ogólne zupełnie pomin ąć rzutowania w dó ł, bowiem oprócz obiektów określonej klasy możemy w kontenerze przechowywa ć równie ż obiekty klas dziedziczących po niej. Typy ogólne mog ą by ć stosowane nie tylko w kontenerach, ale równie ż w zwracanych przez nie iteratorach. Inn ą nowości ą, któr ą możemy stosowa ć wraz z kontenerami jest nowa posta ć pętli for. Oto kod programu ilustrującego użycie list, w którym zastosowano opisane wcześniej nowe elementy Javy: 2, 23 System.out.println(a); 24 for(element e : a) 25 System.out.print(e+" "); 26 System.out.println(); 27 it = a.iterator(); 28 while(it.hasnext()) 29 System.out.print(it.next()+" "); 30 System.out.println(); 31 it=a.iterator(); 32 while(it.hasnext()) { 33 l.addfirst(it.next()); 34 it.remove(); 35 } 36 System.out.println(l); 37 while(!l.isempty()) 1 Korzystając w kontenerach z typów ogólnych sprawiamy, że kontener pamięta klas ę przechowywanych obiektów. Stosowane s ą więc przez niego referencje konkretnej klasy, a nie klasy Object. 2 W języku polskim częściej spotyka si ę obecnie termin typy generyczne. 1

38 System.out.print(l.removeLast()+" "); 39 System.out.println(); 40 } 41 } Należy zaznaczy ć, że nowa posta ć pętli for zapewnia większy stopie ń bezpieczeństwa korzystania z kontenerów, ni ż zwykła instrukcja for, jeśli tworzymy pętle zagnieżdżone. Innym udogodnieniem w korzystaniu z kontenerów jest automatyczne opakowywanie i rozpakowywanie typów podstawowych w odpowiadające im klasy. Ta technika pozwala na stworzenie kontenera, do którego będzie można dodawa ć wartości typu int bez dokonywania dodatkowych zabiegów, które zostan ą za nas wykonane automatycznie. 2. Klasa Arrays W pakiecie java.util znajduje si ę klasa Arrays zawierająca wiele metod statycznych pozwalających na manipulowanie zawartości ą tablic. Metoda fill() wypełnia wszystkie elementy tablicy t ą sam ą wartości ą. Metoda equals() służy do porównywania elementów tablicy. Została ona przeciążona dla typów podstawowych i obiektów klasy Object. Należy pamięta ć, że w przypadku obiektów przechowywanych w tablicy, porównywane s ą ich referencje, a nie zawarto ść pól. Jeśli chcemy porównywa ć pola obiektów, to możemy zrobi ć to na dwa sposoby. Pierwszy polega na zaimplementowaniu przez klas ę obiektów przechowywanych w tablicy interfejsu Comparable i jego metody compareto(). Drugi polega na stworzeniu odrębnej klasy implementującej interfejs Comparator (należy zdefiniowa ć jego metody equals() i compare()). Ten drugi sposób wykorzystujemy wówczas, gdy nie mamy dostępu do kodu klasy przechowywanych obiektów. Tablic ę możemy posortowa ć przy pomocy metody sort(), natomiast przeszuka ć j ą możemy za pomoc ą metody binarysearch(). Kopiowanie tablic najlepiej przeprowadzi ć za pomoc ą metody arraycopy(), która jest metod ą statyczn ą klasy System (nie należy ona do klasy kontenerem 3, który zna klas ę obiektów, które przechowuje (notabene tablice w Javie te ż s ą obiektami). Arrays). Na zakończenie należy zaznaczy ć, że tablica jest jedynym 3. Strumienie 1 import java.io.*; 2 import java.util.*; 3 4 class Rekurencja { 5 private File sciezka; 6 7 public Rekurencja(String nazwa) { 8 sciezka = new File(nazwa); 9 } 10 11 public void start() { 12 walk(sciezka,""); 13 } 14 15 private void walk(file plik,string indent) { 16 String[] lista; 17 File[] pliki; 18 19 lista = plik.list(); 20 pliki = plik.listfiles(); 21 for(int i=0; i<lista.length;i++) 22 System.out.println(indent+lista[i]); 23 indent+=" "; 24 for(int i=0; i<pliki.length;i++) Zbiór klas umożliwiających realizację operacji wejścia wyjścia w Javie jest bardzo duży. Od wersji 1.4 jest on wzbogacony o pakiety klas umożliwiających wykonywanie operacji niskopoziomowych na danych znajdujących si ę w pliku lub innym zasobie. Te pakiety nie będ ą jednak przedstawione na tym wykładzie. Zajmiemy si ę jedynie operacjami wysokopoziomowymi, które umożliwiają nam klasy zgromadzone w pakiecie java.io. Pierwsz ą klas ą z tego pakietu, jaka zostanie tu omówiona jest klasa File. Klasa ta pozwala na przeprowadzanie takich operacji na plikach i katalogach, jak: tworzenie nowych plików i katalogów, przeglądanie katalogów, zmian ę nazwy, usunięcie pliku, obsługę ścieżki do pliku lub katalogu, obsługę atrybutów plików. Oto krótki przykład jak wykorzysta ć obiekt takiej klasy do rekurencyjnego wypisania zawartości bieżącego katalogu: Klasa Rekurencja posiada pole sciezka, które jest klasy File. W konstruktorze tej klasy Rekurencja tworzony jest obiekt klasy File. Przez parametr nazwa przekazywana będzie ścieżka dostępu do pliku, z którym będzie związany ten obiekt (w przypadku tego programu będzie to katalog bieżący). Metoda start() rozpoczyna przeszukiwanie tego katalogu, wywołując metod ę walk(). Ta 3 To stwierdzenie jest prawdziwe dla wersji Javy wcześniejszych ni ż 5. 2

25 if(pliki[i].isdirectory() && pliki[i].canread()) { 26 System.out.println(pliki[i].getName()+":"); 27 walk(pliki[i],indent); 28 } 29 } 30 } 31 32 public class Katalogi { 33 public static void main(string[] args) { 34 Rekurencja r = new Rekurencja("."); 35 r.start(); 36 } 37 } ostatnia jest metod ą rekurencyjn ą. Najpierw zapisuje ona referencj ę do tablicy nazw plików w zmiennej lokalnej lista, a następnie w referencji pliki zapisuje adres tablicy obiektów klasy File związanych z tymi plikami. W pierwszej pętli for wypisywane s ą nazwy plików znajdujących si ę w bieżącym katalogu, w drugiej przeglądania jest tablica obiektów klasy File i sprawdzane jest, które z nich są katalogami i czy można te katalogi przeczyta ć (czy program ma do tego uprawnienia). Dla każdego z tych obiektów wywoływana jest rekurencyjnie metoda walk(). Obiekt klasy Rekurencja tworzony jest w klasie publicznej w metodzie main. Konstruktorowi tego obiektu przekazywana jest nazwa katalogu bieżącego, czyli kropka (.). Jeśli za pomoc ą metod klasy File, chcielibyśmy wyświetli ć pliki, których nazwy pasuj ą do ustalonego przez nas wzorca, to do metody list() powinniśmy przekaza ć obiekt klasy, która implementuje interfejs FilenameFilter i zdefiniowa ć jego metod ę accept, która jest deklarowana następująco: boolean accept(file dir, String name); Klasa implementująca ten interfejs może by ć klas ą anonimow ą. Klasy realizujące operacje wejścia wyjścia w Javie zakładaj ą, że zarówno źródłem jak i ujściem danych s ą strumienie. Strumie ń jest abstrakcją oznaczając ą dowolny element mogący pobiera ć lub przyjmowa ć dane. W Javie, w pakiecie java.io można wyróżni ć trzy grupy klas. Pierwsza grupa związana jest z operacjami binarnymi (nazywanymi równie ż bajtowymi), druga jest związana z operacjami znakowymi (uwzględnia kodowanie za pomoc ą standardu Unicode), natomiast trzecia grupa umożliwia zapis i odczyt obiektów. Podstawowymi klasami pozwalającymi na realizację odczytu i zapisu bajtowego s ą klasy InputStream i OutputStream 4. Jak łatwo si ę domyśli ć metod ą służąc ą do odczytania pojedynczego bajta w klasie InputStream jest metoda read(), natomiast do zapisu pojedynczego bajta w drugiej z wymienionych klas jest write(). Z tych klas wywodzą si ę inne, które związane s ą z obsług ą poszczególnych rodzajów źróde ł i uj ść. Te klasy zostały zestawione poniżej w tabelę 5 : ByteArrayInputStream Klasa Sposób działania Źródłem danych jest tablica znajdująca si ę w pamięci operacyjnej. Sposób użycia Parametrem wywołania konstruktora jest referencja do tablicy z której będ ą pobierane dane. Powinno si ę używa ć razem z obiektami FilterInputStream. StringBuffferInputStream Wykonuje konwersj ę łańcucha znaków do obiektu klasy InputStream. Parametrem wywołania konstruktora jest referencja do obiektu klasy String. Również należy używa ć z obiektami klasy FilterInputStream. FileInputStream Umożliwia odczyt danych z pliku. Argumentem wywołania konstruktora jest łańcuch znaków reprezentujący ścieżkę dostępu do pliku, lub obiekt klasy File związany z tym plikiem lub klasy FileDescriptor. Podobnie jak poprzednio powinno si ę używa ć z obiektami klasy FilterInputStream. PipedInputStream Umożliwia odczyt danych z potoku nienazwanego (ang. pipe) Parametrem wywołania konstruktora tej klasy jest obiekt klasy PipedOutputStream. Obiekty tej klasy s ą używane w aplikacjach wielowątkowych, jako środki umożliwiające komunikacj ę między wątkami. Reszta jak wyżej. 4 Klasy InputStream i OutputStream s ą klasami abstrakcyjnymi, więc wszędzie tam, gdzie będzie mowa o obiektach tych klas, będziemy mie ć na myśli obiekty jej klas pochodnych. 5 Tabela ta jest utworzona na podstawie Thinking in Java Bruce'a Eckela. 3

Klasa Sposób działania Sposób użycia SequenceInputStream Pozwala połączy ć pewn ą liczb ę strumieni wejściowych w jeden strumie ń. Argumentami wywołania s ą dwa obiekty klasy InputStream lub kontener klasy Enumeration zawierający takie obiekty. FilterInputStream Jest to klasa abstrakcyjna służąca za klasę bazow ą dla klas obiektów dekoratorów, obiektów klasy InputStream i pochodnych, które zostan ą opisane później. ByteArrayOutputStream Tworzy bufor w pamięci, do którego będą zapisane dane. Parametr konstruktora jest opcjonalny i określa początkowy rozmiar bufora. Obiekty tej klasy powinny by ć połączone z obiektami klasy FilterOutputStream. FileOutputStream Zapisuje dane do pliku. Argumentem wywołania konstruktora jest łańcuch znaków reprezentujący ścieżkę dostępu do pliku, lub obiekt klasy File związany z tym plikiem lub klasy FileDescriptor. Podobnie jak poprzednio należy używa ć z obiektami klasy FilterOutputStream. PipedOutputStream Umożliwia zapis danych do potoku nienazwanego (ang. pipe) Parametrem wywołania konstruktora tej klasy jest obiekt klasy PipedInputStream. Obiekty tej klasy s ą używane w aplikacjach wielowątkowych, jako środki umożliwiające komunikacj ę między wątkami. Reszta jak wyżej. FilterOutputStream Jest to klasa abstrakcyjna służąca za klasę bazow ą dla klas obiektów dekoratorów, obiektów klasy OutputStream i pochodnych, które zostan ą opisane później. W większości aplikacji napisanych w Javie, aby utworzy ć reprezentacj ę pojedynczego strumienia wejściowego lub wyjściowego tworzy si ę niej jeden lecz kilka obiektów. Pierwszy z tych obiektów jest obiektem której ś z klas wymienionych wyżej, natomiast pozostałe obiekty są dekoratorami, które zwiększaj ą funkcjonalno ść strumienia. Oto zestawienie tych dekoratorów 6 : Klasa Działanie Sposób użycia DataInputStream Umożliwia odczyt danych prostych typów w sposób niezależny od ich faktycznego zapisu w danym systemie. Jego metody, to np.: readbyte(), readfloat(). Argumentem wywołania konstruktora jest obiekt klasy InputStream. BufferedInputStream LineNumberInputStream Używany, w celu przyspieszenia operacji odczytu ze strumienia poprzez zbuforowanie danych. Śledzi numery wierszy w strumieniu wejściowym. Do jego metod nale żą: getlinenumber() i setlinenumber(int) Argument konstruktora taki sam, jak wyżej. Dodatkowy argument może określa ć rozmiar bufora. Obiekty tej klasy nie dostarczają własnych interfejsów. Argument wywołania konstruktora jak poprzednio. Zapewnia numerowanie wierszy. PushBackInputStream DataOutputStream Tworzy bufor o rozmiarze jednego bajta, pozwalający na cofnięcie do strumienia ostatniego odczytanego baja. Umożliwia zapis danych podstawowych typów do strumienia niezależny od platformy. Przykładowe metody: writebyte(), writefloat(). Argument konstruktora jak wyżej. Używany w tworzeniu kompilatorów i innych programów realizujących analiz ę leksykaln ą wejścia. Argumentem konstruktora jest obiekt klasy OutputStream. 6 Na podstawie Thinking in Java Bruce'a Eckela. 4

Klasa Działanie Sposób użycia PrintStream Formatuje dane wyjściowe, decydując o sposobie ich wyświetlania Argument konstruktora jak wyżej. Opcjonalny drugi argument typu boolean określa, czy bufor związany ze strumieniem jest opróżniany po każdej operacji zapisu. BufferOutputStream Buforuje dane do zapisu. Można wymusi ć ich zapisanie wywołując metod ę flush() obiektu tej klasy. Argumentem wywołania konstruktora jest obiekt klasy OutputStream i opcjonalnie rozmiar bufora. Oto przykład realizujący bajtowy odczyt danych z pliku: 1 import java.io.*; 2 class Odczyt { 3 private FileInputStream fs; 4 5 public Odczyt(String s) { 6 try { 7 fs = new FileInputStream(new File(s)); 8 }catch(filenotfoundexception e) { 9 e.printstacktrace(); 10 System.err.println(e.getLocalizedMessage()); 11 }catch(exception e) { 12 e.printstacktrace(); 13 System.err.println(e.getLocalizedMessage()); 14 } 15 } 16 17 public void czytaj() throws IOException { 18 try { 19 int a; 20 while((a=fs.read())!=-1) System.out.print(a); 21 System.out.println(); 22 }catch(ioexception e) { 23 e.printstacktrace(); 24 System.err.println(e.getLocalizedMessage()); 25 }catch(exception e) { 26 e.printstacktrace(); 27 System.err.println(e.getLocalizedMessage()); 28 }finally { 29 fs.close(); 30 } 31 } 32 } 33 5

34 public class OdczytBinarny { 35 public static void main(string[] args) { 36 Odczyt o = new Odczyt("OdczytBinarny.java"); 37 try { 38 o.czytaj(); 39 }catch(ioexception e) { 40 e.printstacktrace(); 41 System.err.println(e.getLocalizedMessage()); 42 }catch(exception e) { 43 e.printstacktrace(); 44 System.err.println(e.getLocalizedMessage()); 45 } 46 } 47 } Odczyt i zapis znakowy realizowany jest przez inne klasy, których funkcjonalno ść odpowiada przedstawionym wyżej klasom. Do tych klas nale żą: Reader, Writer, FileReader, FileWriter, StringReader, StringWriter, CharArrayReader, CharArrayWriter, PipedReader i PipedWriter. Dodatkowo istniej ą klasy umożliwiające konwersj ę strumieni z bajtowych na znakowe. S ą to InputStreamReader i OutputStreamWriter. Klasy odczytu i zapisu znakowego posiadaj ą równie ż własne dekoratory: FilterReader, FilterWriter, BufferReader, BufferWriter, PrintWriter, LineNumberReader, PushBackReader i StreamTokenizer. Ostatni dekorator służy do rozpoznawania wzorców w odczytywanych ze strumienia danych i od wersji 1.4 Javy w dużej mierze zosta ł zastąpiony przez klasy realizujące rozpoznawanie wzorców ( ang. pattern matching). Oto dwa przykłady użycia pokazujące w jaki sposób skorzysta ć ze znakowych operacji odczytu. Pierwszy czyta dane z pliku, natomiast drugi konwertuje strumie ń związany ze standardowym wejściem na strumie ń znakowy i wypisuje jego zawarto ść na ekran: 1 import java.io.*; 2 class Odczyt { 3 private FileReader fs; 4 5 public Odczyt(String s) { 6 try { 7 fs = new FileReader(s); 8 }catch(filenotfoundexception e) { 9 e.printstacktrace(); 10 System.err.println(e.getLocalizedMessage()); 11 }catch(exception e) { 12 e.printstacktrace(); 13 System.err.println(e.getLocalizedMessage()); 14 } 15 } 16 17 public void czytaj() throws IOException { 18 try { 19 char a; 20 while((a=(char)fs.read())!=(char)-1) System.out.print(a); 6

21 System.out.println(); 22 }catch(ioexception e) { 23 e.printstacktrace(); 24 System.err.println(e.getLocalizedMessage()); 25 }catch(exception e) { 26 e.printstacktrace(); 27 System.err.println(e.getLocalizedMessage()); 28 }finally { 29 fs.close(); 30 } 31 } 32 } 33 34 public class OdczytZnakowy { 35 public static void main(string[] args) { 36 Odczyt o = new Odczyt("OdczytZnakowy.java"); 37 try { 38 o.czytaj(); 39 }catch(ioexception e) { 40 e.printstacktrace(); 41 System.err.println(e.getLocalizedMessage()); 42 }catch(exception e) { 43 e.printstacktrace(); 44 System.err.println(e.getLocalizedMessage()); 45 } 46 } 47 } import java.io.*; public class Input { public static void main(string[] args) { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); try { System.out.println(br.readLine()); } catch(exception e) { e.printstacktrace(); } } } 7

Kolejny przykład pokazuje w jaki sposób uży ć dekoratora BufferReader do odczytu pliku: 1 import java.io.*; 2 class Odczyt { 3 private BufferedReader br; 4 5 public Odczyt(String s) { 6 try { 7 br = new BufferedReader(new FileReader(s)); 8 }catch(filenotfoundexception e) { 9 e.printstacktrace(); 10 System.err.println(e.getLocalizedMessage()); 11 }catch(exception e) { 12 e.printstacktrace(); 13 System.err.println(e.getLocalizedMessage()); 14 } 15 } 16 17 public void czytaj() throws IOException { 18 try { 19 String a; 20 while((a=br.readline())!=null) System.out.println(a); 21 System.out.println(); 22 }catch(ioexception e) { 23 e.printstacktrace(); 24 System.err.println(e.getLocalizedMessage()); 25 }catch(exception e) { 26 e.printstacktrace(); 27 System.err.println(e.getLocalizedMessage()); 28 }finally { 29 br.close(); 30 } 31 } 32 } 33 34 public class OdczytBuforowany { 35 public static void main(string[] args) { 36 Odczyt o = new Odczyt("OdczytBuforowany.java"); 37 try { 38 o.czytaj(); 39 }catch(ioexception e) { 40 e.printstacktrace(); 8

41 System.err.println(e.getLocalizedMessage()); 42 }catch(exception e) { 43 e.printstacktrace(); 44 System.err.println(e.getLocalizedMessage()); 45 } 46 } 47 } Opisane wyżej klasy słu żą do realizacji operacji wejścia wyjścia na zasadzie dostępu sekwencyjnego, jeśli jest nam potrzebny dostęp swobodny, możemy skorzysta ć z metod klasy RandomAccesFile. Java standardowo zawiera równie ż klasy umożliwiające zapis i odczyt plików skompresowanych. Istniej ą równie ż dwie klasy, związane ze strumieniami binarnymi (bajtowymi), które umożliwiaj ą zapis i odczyt obiektów. Takie operacje nazywa si ę operacjami serializacji obiektów. Te klasy to ObjectInputStream i ObjectOutputStream. Pierwsza posiada metodę readobject(), druga writeobject(). Aby obiekt móg ł by ć zapisany do strumienia jego klasa musi implementowa ć interfejs Serializable, który nie deklaruje żadnej metody, a pełni tylko funkcj ę znacznika, wskazującego, że obiekt danej klasy może by ć zapisany lub odczytany ze strumienia. Należy pamięta ć o tym, że metoda readobject() zwraca referencj ę klasy Object, a więc konieczne jest rzutowanie w dó ł, aby odtworzy ć właściwą klas ę obiektu. Jeśli nie chcemy, aby pewne informacje przechowywane w polach obiektu były zapisywane w pliku, to takie pole deklarujemy z użyciem słowa kluczowego transient. Inn ą metoda polega na implementowaniu interfejsu Externalizable zamiast Serializable i zdefiniowaniu jego metod writeexternal() i readexternal(), w których trzeba zawrze ć kod odpowiedzialny za zapis poszczególnych pól obiektu. 9