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

Podobne dokumenty
Strumienie i serializacja

STRUMIENIE DANYCH, SERIALIZACJA OBIEKTÓW

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

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

Podstawy i języki programowania

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

Programowanie w języku Java - Wyjątki, obsługa wyjątków, generowanie wyjątków

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

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

Programowanie obiektowe

Programowanie obiektowe

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

Strumienie, pliki. Sortowanie. Wyjątki.

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

Programowanie Obiektowe Ćwiczenie 4

Programowanie Obiektowe (Java)

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

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

Obsługa błędów za pomocą wyjątków. Paweł Motofa (140746)

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

Kurs programowania. Wykład 1. Wojciech Macyna. 3 marca 2016

Platformy Programistyczne Zagadnienia sieciowe i wątki

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

Programowanie obiektowe

Programowanie obiektowe

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

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

Strumienie, pliki. Sortowanie. Wyjątki.

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

Wykład 2: Podstawy Języka

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

Programowanie w języku Java WYKŁAD

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

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

Aplikacje w środowisku Java

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

Bezpieczne uruchamianie apletów wg

Kurs programowania. Wykład 3. Wojciech Macyna. 22 marca 2019

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

Java podstawy jęyka. Wykład 2. Klasy abstrakcyjne, Interfejsy, Klasy wewnętrzne, Anonimowe klasy wewnętrzne.

Dokumentacja do API Javy.

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

Wyjątki. Streszczenie Celem wykładu jest omówienie tematyki wyjątków w Javie. Czas wykładu 45 minut.

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

Dawid Gierszewski Adam Hanasko

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

Strumienie tekstowe (wprowadzanie danych z klawiatury) i bajtowe, otwieranie strumieni przez sieć - obiekty URL

sieć 4) Mechanizm RMI jest zazwyczaj wykorzystywany w rozwiązaniach typu klient-serwer.

Java. Programowanie Obiektowe Mateusz Cicheński

Wykład 2 Wybrane konstrukcje obiektowych języków programowania (1)

Programowanie obiektowe

Zdalne wywołanie metod - koncepcja. Oprogramowanie systemów równoległych i rozproszonych Wykład 7. Rodzaje obiektów. Odniesienie do obiektu

Wywoływanie metod zdalnych

Programowanie obiektowe

Oprogramowanie systemów równoległych i rozproszonych Wykład 7

Metody zawarte w klasie File: boolean createnewfile() tworzy nowy, pusty plik, ale tylko jeśli on wcześniej nie istniał. boolean delete() usuwa dany

Programowanie obiektowe zastosowanie języka Java SE

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

Zad.30. Czy można utworzyć klasę, która implementuje oba interfejsy?

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

Programowane refleksyjne i serializacja

Programowanie obiektowe

JAVA W SUPER EXPRESOWEJ PIGUŁCE

Programowanie rozproszone w języku Java

Przygotował: Jacek Sroka 1. Java SE. Strumienie

Remote Method Invocation 17 listopada Dariusz Wawrzyniak (IIPP) 1

Katalog książek cz. 2

Podejście obiektowe do budowy systemów rozproszonych

Programowanie w Internecie. Java

Remote Method Invocation 17 listopada 2010

Metody dostępu do danych

WYJĄTKI. Jest ona jednak czasochłonna i prowadzi do duŝego zapotrzebowania na zasoby systemu.

Podejście obiektowe do budowy systemów rozproszonych

Java RMI. Dariusz Wawrzyniak 1. Podejście obiektowe do budowy systemów rozproszonych. obiekt. interfejs. kliencka. sieć

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

Java SE Laboratorium nr 4. Temat: Obsługa wyjątków i zdarzeń

Podstawy programowania obiektowego

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

Wyjątki (exceptions)

Wyjątki Monika Wrzosek (IM UG) Programowanie obiektowe 180 / 196

Wywoływanie metod zdalnych

Programowanie obiektowe

Aplikacja wielowątkowa prosty komunikator

public - może być używana w kodzie poza klasą, jedna klasa ModyfikatorKlasy może być kombinacją wyrażeń:

Polimorfizm, metody wirtualne i klasy abstrakcyjne

JAVA I SIECI. MATERIAŁY:

Metody Metody, parametry, zwracanie wartości

Java RMI. Dariusz Wawrzyniak 1. Podejście obiektowe do budowy systemów rozproszonych. obiekt. interfejs. kliencka. sieć

1 Atrybuty i metody klasowe

Java: kilka brakujących szczegółów i uniwersalna nadklasa Object

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

Programowanie obiektowe

Wykład 04. Programowanie obiektowe. Maciej Wołoszyn 17 marca Spis treści

dr Krzysztof Podlaski

Klasy cd. Struktury Interfejsy Wyjątki

Zaawansowane techniki programowania C#

Java. Wykład. Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ

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

Programowanie urządzeń mobilnych. dr inż. Andrzej Grosser na podstawie wykładu dr inż. Juliusza Mikody

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

Transkrypt:

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

Wyjątki Podstawą filozofii Javy jest założenie, że: źle sformułowany kod nie zostanie wykonany Wyjątki są mechanizmem zabezpieczającym program podczas jego działania dynamicznie (w odróżnieniu od błędów pojawiających się podczas kompilacji przy statycznym sprawdzaniu poprawności programu). Stanowią element sięgający podstaw języka i szeroko stosowany we wszelkich bibliotekach Java. Lepiej jest przerwać wykonywanie programu, niż dopuścić do nieoczekiwanych efektów wynikających z błędu.

Typowa obsługa wyjątków Sytuacja błędna powoduje utworzenie nowego obiektu wyjątku i rzucenie go. Kod, który wyrzuca wyjątki można spróbować wykonać, a pojawiające się wyjątki można łapać. Złapany wyjątek można obsłużyć albo rzucić ponownie. Jeśli kod w metodzie rzuca wyjątek (nie jest on obsłużony), musi być to wyspecyfikowane w deklaracji metody. Można także wskazać finalne operacje wykonywane zawsze, niezależnie od tego czy wyjątek wystąpił, czy nie. Wyjątki pochodzą od klasy java.lang.throwable, jej główne podklasy to: java.lang.exception (najczęściej używana), java.lang.runtimeexception oraz java.lang.error.

Kategorie wyjątków Exception do typowej obsługi wyjątków. Tworząc własne klasy wyjątków najczęściej dziedziczy się je właśnie z tej klasy. RuntimeException oraz pochodne określają wyjątki, które mogą pojawić się podczas normalnego działania maszyny wirtualnej. Nie trzeba deklarować ich w definicjach metod, mogą pojawić się w każdej metodzie. Przykłady: NullPointerException, IndexOutOfBoundsException. Error oraz pochodne określają poważne problemy, sytuacje, które nie powinny zdarzyć się przy normalnym wykonaniu programu. Nie trzeba deklarować ich w definicjach metod. Przykłady: VirtualMachineError, AssertionError.

Łapanie wyjątków Odbywa się z użyciem bloków try i catch. Pierwszy blok (try spróbuj) obejmuje kod, który może spowodować wyjątek. Drugi blok (catch złap) określa jakie wyjątki chce obsłużyć i zawiera kod z obsługą błędów. Jeśli wyjątek został złapany, można m.in. wyświetlić informację o pochodzeniu błędu (jest to najczęściej używane): ex.printstacktrace() odczytać komunikat błędu: ex.getmessage() odczytać źródło błędu: ex.getcause()

Łapanie wyjątków przykład (1) import java.io.*; public class Imie { static void odczytajimie() { BufferedReader in = new BufferedReader( new InputStreamReader(System.in)); try { System.out.print("Podaj imie: "); blok try String imie = in.readline(); // może być wyjątek System.out.print("Witaj " + imie + "!"); catch (IOException e) { e.printstacktrace(); lokalna obsługa wyjątku public static void main(string[] args) { odczytajimie();

Łapanie wyjątków przykład (2) import java.io.*; specyfikacja wyjątku public class Imie { static void odczytajimie() throws IOException { BufferedReader in = new BufferedReader( new InputStreamReader(System.in)); System.out.print("Podaj imie: "); String imie = in.readline(); // tu może być wyjątek System.out.print("Witaj " + imie + "!"); public static void main(string[] args) { try { blok try odczytajimie(); catch (IOException e) { e.printstacktrace(); obsługa wyjątku

Rzucanie wyjątków Aby zasygnalizować błąd, należy utworzyć obiekt wyjątku (podając przyczynę błędu). Następnie należy rzucić wyjątek, z użyciem słowa kluczowego throw: long suma = 0; int iloscnieujemnych = 0; void dodajnieujemna(int liczba) throws IllegalArgumentException { if (liczba > 0) { suma += liczba; iloscnieujemnych++; else { throw new IllegalArgumentException("liczba <= 0");

Tworzenie własnych klas wyjątków Nowa klasa wyjątku powinna dziedziczyć z Exception. Może zawierać dodatkowe pola i metody. Powinna deklarować przynajmniej dwa konstruktory: bezparametrowy z jednym argumentem typu String public class ProgramException extends Exception { public ProgramException() { super(); public ProgramException(String message) { super(message);

Własne klasy wyjątków oraz wiązanie wyjątków Żeby móc używać mechanizmu wiązania wyjątków, wskazane jest dodanie jeszcze dwóch konstruktorów: z jednym argumentem typu Throwable z argumentami typu String oraz typu Throwable public class ProgramException extends Exception { public ProgramException() { super(); public ProgramException(String message) { super(message); public ProgramException(Throwable cause) { super(cause); public ProgramException(String message, Throwable cause) { super(message, cause);

Wiązanie wyjątków Wiązanie wyjątków (exception chaining) pozwala dowiedzieć się jaka była oryginalna przyczyna powstania wyjątku w przypadku, gdy wyjątek jest rzucany ponownie: void openfile() throws ProgramException { FileReader file = null; try { String filename = selectfile(); file = new FileReader(fileName); parsecontents(file); catch (IOException ex) { throw new ProgramException("Błąd odczytu pliku: " + ex.getmessage(), ex); catch (NumberFormatException ex) { throw new ProgramException("Błędny format pliku: " + ex.getmessage(), ex); finally { if (file!= null) try { file.close(); /* mamy wyjątek - zrób porządki i zamknij plik */ catch (IOException ex) { /* pominięcie ew. błędów */

Efekt wiązania wyjątków public class Program { public static void main(string[] args) { try { openfile(); catch (ProgramException ex) { ex.printstacktrace(); > java Program ProgramException: Błąd odczytu pliku: test.txt (No such file or directory) at Program.openFile(Program.java:34) at Program.main(Program.java:15) Caused by: java.io.filenotfoundexception: test.txt (No such file or directory) at java.io.fileinputstream.open(native Method) at java.io.fileinputstream.<init>(fileinputstream.java:106) at java.io.fileinputstream.<init>(fileinputstream.java:66) at java.io.filereader.<init>(filereader.java:41) at Program.openFile(Program.java:30)... 1 more

Dziedziczenie klas wyjątków Kolejność zapisu sekcji catch ma znaczenie, ponieważ przy wystąpieniu wyjątku są one przeglądane w kolejności występowania. Pierwsze dopasowanie do klasy wyjątku pomija pozostałe sekcje catch. Pojawiają się błędy kompilacji, gdy obsługa wyjątków klas bardziej ogólnych poprzedza obsługę wyjątków klas pochodnych. Kod zawarty w sekcji finally wykonywany jest zawsze, niezależnie od tego czy wystąpił wyjątek, czy nie. Służy to do czynności porządkowych, zwalniania zasobów, itp.

Podsumowanie Aby stworzyć niezawodny system, każdy jego komponent musi być niezawodny Obsługa wyjątków jest kluczowym sposobem zwiększenia niezawodności programów. Drugim sposobem jest używanie testów jednostkowych i testów modułowych (unit testing, module testing). Java wymusza wiele aspektów związanych z wyjątkami, co gwarantuje, że będą one spójnie używane zarówno przez twórców jak i użytkowników bibliotek.

Podstawy otwartych języków programowania Strumienie wejścia/wyjścia Wiktor Wandachowicz

Strumienie danych Strumień jest abstrakcyjną reprezentacją dowolnego źródła lub ujścia danych Na podstawie dwóch logicznych operacji wyróżniamy dwa typy strumieni: strumienie wejściowe (odczyt danych) strumienie wyjściowe (zapis danych) Strumień jest zawsze stowarzyszony z jakimś źródłem danych (odczyt) lub ujściem (zapis). Wyróżniamy także strumienie bajtowe i znakowe. W Javie obsługę strumieni zapewnia pakiet java.io

Strumienie wejściowe i wyjściowe strumień wejściowy źródło danych informacja odczyt Program strumień wyjściowy Program zapis informacja ujście danych

Algorytmy odczytu i zapisu Odczyt otwórz strumień jeśli jest jeszcze informacja [określane przez źródło] odczytaj informację zamknij strumień Zapis otwórz strumień jeśli jest jeszcze informacja [określane przez program] zapisz informację zamknij strumień

Hierarchia strumieni Strumienie bajtowe Strumienie znakowe Klasy strumieni są w pakiecie java.io Przy nieudanych operacjach pojawiają się wyjątki klasy java.io.ioexception Strumienie bajtowe i znakowe zapewniają praktycznie taką samą funkcjonalność (API), różnią się głównie obsługiwanymi typami danych.

Strumienie bajtowe Dwa najbardziej ogólne strumienie bajtowe to: InputStream do odczytu, oraz OutputStream do zapisu ciągów bajtów. void close() InputStream abstract int read() int read(byte[] b) int read( byte[] b, int off, int len) long skip(long n) abstract void write(int b) void write(byte[] b) void write( byte[] b, int off, int len) void flush() void close() OutputStream

Strumienie znakowe Podstawowymi strumieniami znakowymi są: Reader do odczytu, oraz Writer do zapisu ciągów znaków. int read() void close() Reader int read(char[] cbuf) abstract int read(char[] cbuf, int off, int len) long skip(long n) void write(int c) void write(char[] cbuf) abstract void write(char[] cbuf, int off, int len) void flush() void close() Writer

Rozszerzanie funkcjonalności Zwiększenie funkcjonalności odbywa się przez użycie wyspecjalizowanych strumieni. Korzystają one z innych strumieni, aby wykonywać swoją pracę. Robi się to przez opakowanie jednego typu strumienia w inny (aby to zadziałało musi istnieć w wybranej klasie strumienia odpowiedni konstruktor). InputStream int read(byte[] b) InputStreamReader int read(char[] cbuf) BufferedReader String readline()

Odczyt standardowego wejścia (Java 1.0 1.4) import java.io.*; public class PowielajLinie { public static void main(string[] args) throws IOException { System.out.println("Wpisuj linie tekstu. " + "Koniec gdy pusta linia."); BufferedReader in = new BufferedReader( new InputStreamReader(System.in)); String linia; do { linia = in.readline(); System.out.println(linia); while (linia.length() > 0); InputStream

Odczyt standardowego wejścia (Java 5, 6) import java.io.*; import java.util.scanner; public class PowielajLinie2 { public static void main(string[] args) { System.out.println("Wpisuj linie tekstu. " + "Koniec gdy pusta linia."); Scanner sc = new Scanner(System.in)); String linia; do { linia = sc.nextline(); System.out.println(linia); while (linia.length() > 0); InputStream

Odczyt i zapis plików Żeby otworzyć plik, wystarczy stworzyć obiekt wybranej klasy, podając nazwę pliku w postaci łańcucha znaków lub obiektu klasy File. FileInputStream odczyt pliku binarnego FileOutputStream zapis pliku binarnego (*) FileReader odczyt pliku znakowego FileWriter zapis pliku znakowego (*) (*) możliwe otwarcie pliku do dopisywania, bez usuwania poprzedniej zawartości Otwarty strumień można opakować w wybrany strumień wyspecjalizowany Po zakończeniu strumień należy zamknąć close()

Klasa File NIE JEST to plik służy raczej jako opis ścieżek do plików lub katalogów (klasa ta równie dobrze mogłaby nazywać się FilePath): File plik = new File("plik.txt"); FileReader in = new FileReader(plik); Przy użyciu tej klasy można także m.in. sprawdzać informacje o pliku: isdirectory(), isfile(), canread(), canwrite(), exists(), length(), lastmodified() wykonywać operacje na plikach i katalogach: delete(), mkdir(), mkdirs(), renameto() odczytywać zawartość katalogu: list(), listfiles()

Strumienie specjalizowane Zamiana strumieni bajtowych na znakowe: InputStreamReader / OutputStreamWriter Odczyt i zapis z uwzględnieniem znaków końca linii: BufferedReader readline() BufferedWriter newline() Strumień z buforem (większa wydajność): BufferedInputStream / BufferedOutputStream Przeciążone metody println(): PrintStream / PrintWriter

Strumienie specjalizowane Odczyt i zapis tablic bajtów lub znaków (w pamięci): ByteArrayInputStream / ByteArrayOutputStream CharArrayReader / CharArrayWriter Odczyt i zapis łańcuchów napisów (w pamięci): StringReader / StringWriter Odczyt i zapis plików (bajtowo i znakowo): FileInputStream / FileOutputStream FileReader / FileWriter Serializacja obiektów: ObjectInputStream / ObjectOutputStream

Klasa Osoba (JavaBean) public class Osoba { private String imie; private String nazwisko; public Osoba() { public String getimie() { return imie; public void setimie(string noweimie) { this.imie = noweimie; public String getnazwisko() { return nazwisko; public void setnazwisko(string nowenazwisko) { this.nazwisko = nowenazwisko; // opcjonalny dodatkowy konstruktor // (łatwiejsze tworzenie obiektów) public Osoba(String imie, String nazwisko) { this.imie = imie; this. nazwisko = nazwisko;

Zapis i odczyt danych w pliku import java.util.*; import java.io.*; public class ZapisOdczyt { private static List<Osoba> osoby = new ArrayList<Osoba>(); public static void main(string[] args) throws IOException { osoby.add(new Osoba("Jan", "Kowalski")); osoby.add(new Osoba("Adam", "Nowak")); zapisz(); osoby.clear(); odczytaj(); wyswietl(); private static void wyswietl() { int nr = 1; for (Osoba o : osoby) { System.out.println(" " + (nr++) + ". " + o.getimie() + " " + o.getnazwisko());

Zapis i odczyt danych w pliku private static void zapisz() throws IOException { PrintWriter plik = new PrintWriter( new BufferedWriter(new FileWriter("dane.txt"))); for (Osoba o : osoby) { plik.println(o.getimie() + ":" + o.getnazwisko()); plik.close(); private static void odczytaj() throws IOException { BufferedReader plik = new BufferedReader( new FileReader("dane.txt")); while (plik.ready()) { String s = plik.readline(); String[] dane = s.split(":"); osoby.add(new Osoba(dane[0], dane[1])); plik.close();

Serializacja Serializacja pozwala zamienić obiekt na sekwencję bajtów,, w sposób umożliwiający później wierne odtworzenie jego zawartości Inna nazwa to trwałość (ang. persistence) cecha oznaczająca, że życie obiektu nie jest ograniczone tylko do czasu działania programu. Format binarny, skuteczny również w sieci pomiędzy komputerami działającymi pod różnymi JVM. Dużo klas z bibliotek Javy jest zmodyfikowanych tak, że wspierają serializację (np. kolekcje).

Zastosowania serializacji Trwałość zapisanie obiektów na dysk oraz odtworzenie przy kolejnym uruchomieniu programu. Zdalne wywoływanie metod między komputerami poprzez RMI (ang. Remote Method Invocation). Pozwala to obiektowi istniejącemu na jednym komputerze zachowywać się tak, jakby istniał na drugim komputerze. Serializacja jest używana do przekazywania argumentów przy wywołaniu metod odległego obiektu oraz do zwracania wartości. Komponenty JavaBeans elementy z których buduje się interfejs użytkownika. W trakcie projektowania stan komponentu jest serializowany, a przy starcie programu jest on odtwarzany.

Sposoby realizacji Serializację typowo realizuje się przez: 1. Implementację interfejsu Serializable w klasie, która ma być serializowana (nie ma żadnych metod, jest znacznikiem ). Można także kontrolować przebieg serializacji przez: 2. Implementację w klasie interfejsu Externalizable oraz jego dwóch metod: writeexternal() zapis obiektu i readexternal() odczyt obiektu, musi być też dostępny publiczny konstruktor domyślny. 3. Implementację w klasie interfejsu Serializable oraz dodatkowo (!) dwóch prywatnych metod writeobject() i readobject().

Działanie Żeby zserializować obiekt, trzeba utworzyć strumień ObjectOutputStream i wywołać jego metodę writeobject() podając obiekt do serializacji. Może się tu pojawić wyjątek IOException. Żeby odtworzyć obiekt, trzeba utworzyć strumień ObjectInputStream, wywołać jego metodę readobject() i dokonać rzutowania (readobject() zwraca bowiem obiekt klasy Object). Mogą się tu pojawić wyjątki IOException oraz ClassNotFoundException. Słowo kluczowe transient pozwala wskazać, które składowe obiektu mają nie być serializowane.

Przykład serializowania obiektów import java.io.*; class Wezel implements Serializable { String nazwa; /*... */ public class Serializacja { Wezel korzen = new Wezel(); /*... */ void zapiszwezly() throws IOException { /*... utworzenie strumienia wyjściowego... */ ObjectOutputStream out = new ObjectOutputStream( /*strumień wyj.*/ ); out.writeobject(korzen); /*... zamknięcie strumienia wyjściowego... */

Przykład odtwarzania obiektów /*... */ void przywrocwezly() throws IOException, ClassNotFoundException { /*... utworzenie strumienia wejściowego... */ ObjectInputStream in = new ObjectInputStream( /*strumień wej.*/ ); // odczytanie obiektu i rzutowanie do // odpowiedniego typu korzen = (Wezel) in.readobject(); /*... zamknięcie strumienia wejściowego... */