background image

5. Strumienie wej

ś

cia - wyj

ś

cia 

W. Kasprzak: Programowanie zdarzeniowe 

5 - 1 

 

5. Strumienie wej

ś

cia – wyj

ś

cia 

 

5.1 Klasy strumieni WE-WY  
5.2 Korzystanie ze strumieni 
5.3 Serializacja obiektów 
5.4 Pliki o dost

ę

pie swobodnym

 

5. Strumienie wej

ś

cia - wyj

ś

cia 

W. Kasprzak: Programowanie zdarzeniowe 

5 - 2 

5.1 Klasy strumieni WE-WY  

Klasy  w  pakiecie 

java.io

  słu

Ŝą

  do  obsługi 

strumieni  wej

ś

cia  -  wyj

ś

cia

 

(które mog

ą

 zosta

ć

 otwarte dla 

pliku, pami

ę

ci, gniazdka,

 itd., a nast

ę

pnie 

odczytane lub zapisane sekwencyjnie). 

Strumień danych

ODCZYT

Ź

ródło

  

Strumień danych

ZAPIS

Cel

 

Bez wzgl

ę

du na rodzaj strumienia sposób współpracy jest ten sam: 

 Odczyt 

Zapis 



 

OTWÓRZ 



 

while JEST_INFORMACJA 

       ODCZYT 


 

ZAMKNIJ_STRUMIEŃ 



 

OTWÓRZ 



 

while JEST_INFORMACJA 

        ZAPIS 


 

ZAMKNIJ_STRUMIEŃ 

Podział klas we-wy w  

java.io

 - ze wzgl

ę

du 

na dane

 na których operuj

ą



 znakowe strumienie  

i

  



 bajtowe strumienie. 

background image

5. Strumienie wej

ś

cia - wyj

ś

cia 

W. Kasprzak: Programowanie zdarzeniowe 

5 - 3 

1) Strumienie znakowe 

Reader,  Writer

  to  abstrakcyjne  klasy  bazowe  dla  strumieni  znakowych 

(zawieraj

ą

 implementacje cz

ęś

ci metod). 

 

Klasy pochodne od 

Reader

 i 

Writer

-  dla odczytu/zapisu danych (na szarym tle
-  wykonuj

ą

ce pewne przetwarzanie (na białym tle). 

 

5. Strumienie wej

ś

cia - wyj

ś

cia 

W. Kasprzak: Programowanie zdarzeniowe 

5 - 4 

 

2) Strumienie bajtowe 

InputStream,  OutputStream

  -  bazowe  klasy  dla  odczytu/zapisu  8-

bitowych 

binarnych

 danych. 

Klasy pochodne

 od 

InputStream, OutputStream

-  dla odczytu/zapisu danych (na szarym tle
-  wykonuj

ą

ce pewne przetwarzanie (na białym tle). 

ObjectInputStream,  ObjectOutputStream

  -  klasy  przeznaczone  do 

deserializacji i serializacji obiektu

background image

5. Strumienie wej

ś

cia - wyj

ś

cia 

W. Kasprzak: Programowanie zdarzeniowe 

5 - 5 

 

 

 

5. Strumienie wej

ś

cia - wyj

ś

cia 

W. Kasprzak: Programowanie zdarzeniowe 

5 - 6 

3) Klasa 

Reader  

Klasa 

Reader 

zawiera metody dla 

odczytu

 znaków i tablic 

znaków

// Deklaracja klasy i jej składowych

 

public abstract class Reader extends Object { 

 

// Pole dla synchronizacji dost

ę

pu 

protected Object lock

// Zamiast obiektu klasy 

Reader

 synchronizacj

ę

  

dost

ę

pu w

ą

tków do obiektu strumieniowego zapewni jego pole. 

// Konstruktory 

protected Reader(); 

// Konstruktor strumienia znakowego dla odczytu - 

// synchronizacja na obiekcie klasy. 

protected Reader(Object lock); 

// - synchronizacja na zadanym obiekcie.  

// Metody steruj

ą

ce stanem i informuj

ą

ce o stanie strumienia 

abstract void close(); 

// Zamyka strumień. 

void mark (int readAheadLimit); 

// Wstawia znacznik w aktualnej pozycji. 

boolean markSupported(); 

//Informuje czy strumień posiada operację mark 

boolean ready (); 

// Czy strumień jest gotowy do odczytu

.  

void reset (); 

// Powróć do ostatniego znacznika.

  

background image

5. Strumienie wej

ś

cia - wyj

ś

cia 

W. Kasprzak: Programowanie zdarzeniowe 

5 - 7 

long skip (long n); 

// Pomiń n znaków.

  

// 3 wersje metody read() 

int read (); 

// Czytaj pojedynczy znak.

  

int read (char[] cbuf); 

// Wczytaj znaki do tablicy.

  

abstract int read (char[] cbuf, int off, int len); 

// Wczytaj znaki do tablicy w 

// określone miejsce

.  

 

4) Klasa

 InputStream

  

Klasa 

InputStream

 

posiada metody dla odczytu bajtów i tablic bajtów. 

// Deklaracja klasy i jej składowych. 

public abstract class InputStream extends Object { 

public InputStream(); 

// Konstruktor 

// 3 wersje metody read() 

public abstract int read()  throws IOException; 

// Metoda abstrakcyjna

 

public int read(byte[] b)  throws IOException; 

//  2 

public int read(byte[] b,  int offset, int length) throws IOException;

 // 3 

// Wersje 2 i 3 s

ą

 zdefiniowane.

 

5. Strumienie wej

ś

cia - wyj

ś

cia 

W. Kasprzak: Programowanie zdarzeniowe 

5 - 8 

public void close() throws IOException; 

// Zamyka strumie

ń

 i zwalnia  

// jego zasoby - metoda musi by

ć

 nadpisana. 

// 
// Sterowanie pozycj

ą

 znacznika w strumieniu. 

public long skip(long n)  throws IOException; 

// Przeskoczy

ć

 pewn

ą

  

// liczb

ę

 bajtów – metoda musi by

ć

 nadpisana

 

public int available() throws IOException; 

// Zwraca liczb

ę

 bajtów, które 

// mog

ą

 zosta

ć

 odczytane bez blokowania strumienia - metod

ę

 trzeba 

// nadpisa

ć

.

 

public void reset() throws IOException; 

// Powraca do ostatniego  

// znacznika - metoda musi zosta

ć

 nadpisana w klasach pochodnych.

 

public void mark(int readlimit); 

// Wstawia znacznik i ustawia limit 

// odczytu - metoda musi zosta

ć

 nadpisana w klasach pochodnych

 

public boolean markSupported();

// Sprawdza czy istniej

ą

 

mark()

 i 

reset()

 

 

background image

5. Strumienie wej

ś

cia - wyj

ś

cia 

W. Kasprzak: Programowanie zdarzeniowe 

5 - 9 

5) Klasa

 Writer

  

Klasa 

Writer

 posiada metody dla zapisu znaków i tablic znaków. 

public abstract class Writer  extends Object { 

// Konstrukcja i synchronizacja 

protected Objeck lock

// Zamiast obiektu synchronizację zapewni jego pole

protected Writer(); 

// Konstrukcja strumienia samo-synchronizowanego.

 

protected Writer(Object lock

);//Konstrukcja strumienia synchronizowanego 

// przekazanym obiektem. 

// Sterowanie stanem 

abstract void close(); 

// Wykonaj flush() i zamknij strumień

abstract void flush(); 

// Zapisz wszystko co jest w buforze do strumienia. 

// 5 wersji metody 

write() 

void write(char[] cbuf); 

// Zapisz tablicę znaków.

  

abstract void write(char[] cbuf, int off, int len); 

// Zapisz część tablicy

  

void write (int c); 

// Zapisz pojedynczy znak.  

void write(String str); 

// Zapisz string.

  

void write(String str, int off, int len); 

// Zapisz część string-a.  

5. Strumienie wej

ś

cia - wyj

ś

cia 

W. Kasprzak: Programowanie zdarzeniowe 

5 - 10 

6) Klasa

 OutputStream

  

Klasa 

OutputStream

 posiada metody zapisu dla bajtów. 

public abstract class OutputStream extends Object { 

// Konstruktor 

public OutputStream(); 

// Sterowanie stanem 

void close(); 

// Zamknij strumień, zwolnij jego zasoby systemowe.

  

void flush(); 

// Wypełnij strumień i wypisz wszystko z bufora.

  

// 3 wersje metody write() 

void write (byte[] b); 

// Wypisz liczbę (b.length) bajtów z tablicy b

.  

void write (byte[] b, int off, int len); 

// Wypisz liczbę (len) bajtów z tablicy.

   

abstract void write (int b); 

// Wypisz  podany bajt.

  

background image

5. Strumienie wej

ś

cia - wyj

ś

cia 

W. Kasprzak: Programowanie zdarzeniowe 

5 - 11 

7) Otwarcie i zamkni

ę

cie strumienia 

Otwarcie strumienia:  



 automatycznie  w  chwili  utworzenia  obiektu  strumienia  typu 

Reader,

 

Writer, InputStream, OutputStream

. 

 
Zamkni

ę

cie strumienia: 



 wykonanie  metody 

close

  strumienia,  lub  poleganie  na  "

Garbage 

Collector

". 

5. Strumienie wej

ś

cia - wyj

ś

cia 

W. Kasprzak: Programowanie zdarzeniowe 

5 - 12 

5.2 Korzystanie ze strumieni 

1) Strumienie plikowe (

FileReader, FileWriter, FileInputStream, 

FileOutputStream

Mo

Ŝ

na utworzy

ć

 strumie

ń

 plikowy: 



 dla pliku przekazanego w postaci napisu (

string)

,  



 dla obiektu klasy 

File

 lub  



 dla obiektu klasy 

FileDescription

Przykład.

  Wykorzystanie  klas 

FileReader

  i 

FileWriter

  dla  skopiowania 

zawarto

ś

ci pliku 

plikWE.txt

 do pliku 

plikWY.txt

import java.io.*; 
public class PrzykladKopiowaniaPlikow { 
    public static void main(String[] args) throws IOException { 

    File inputFile = new File("plikWE.txt");  

// Obiekt klasy File  

    File outputFile = new File("plikWY.txt"); 

// Obiekt klasy File 

    FileReader in = new FileReader(inputFile); 

// Utwórz "FileReader-a"

 

    FileWriter out = new FileWriter(outputFile); 

// Utwórz "FileWriter-a"

 

        int c; 

background image

5. Strumienie wej

ś

cia - wyj

ś

cia 

W. Kasprzak: Programowanie zdarzeniowe 

5 - 13 

        while ((c = in.read()) != -1)    
   

 out.write(c);  

// Odczyt z pliku we. i zapis do pliku wy.

 

    in.close(); 

// Zamknij plik wejściowy

   

    out.close(); 

// Zamknij plik wyjściowy

 

    } 

 

2) Pochodne klasy strumieniowe w 

java.io

 

Typ we-wy 

Klasy strumieni 

Opis 

CharArrayReader 
CharArrayWriter 
ByteArrayInputStream 
ByteArrayOutputStream 

Strumieniowy odczyt/zapis z /do tablicy 
w pami

ę

ci programu. 

Pami

ęć

 

StringReader 
StringWriter 
StringBufferInputStream 

StringReader

 - odczyt znaków ze 

String

-

u w pami

ę

ci. 

StringWriter

 - zapis 

znaków z wewn

ę

trznego 

StringBuffer

 

do 

String

-a. 

StringBufferInputStream 

odczyt bajtów ze 

StringBuffer

5. Strumienie wej

ś

cia - wyj

ś

cia 

W. Kasprzak: Programowanie zdarzeniowe 

5 - 14 

 

 

 

Plik 

FileReader 
FileWriter 
FileInputStream 
FileOutputStream 

Odczyt/zapis z/do pliku zewn

ę

trznego. 

 

 

 

Potok 

PipedReader 
PipedWriter 
PipedInputStream 
PipedOutputStream 

Potoki przeprowadzaj

ą

 wyj

ś

cie z 

jednego strumienia w wej

ś

cie dla 

drugiego.  

 

 

 

Konkate-
nacja 

znakowe - N/A 
SequenceInputStream 

Ł

ą

czy wiele strumieni wej

ś

ciowych w 

jeden. 

 

 

 

Serializacja 
obiektu 

znakowe - N/A 
ObjectInputStream 
ObjectOutputStream 

Utrwalenie stanu obiektu i odczytanie 
wcze

ś

niej utrwalonego stanu obiektu.  

 
 

 

 

background image

5. Strumienie wej

ś

cia - wyj

ś

cia 

W. Kasprzak: Programowanie zdarzeniowe 

5 - 15 

Konwersja 
danych 

znakowe - N/A  
DataInputStream 
DataOutputStream 

Odczyt/zapis prostych typów danych 
do formatu niezale

Ŝ

nego od maszyny. 

 

 

 

Zliczanie 

LineNumberReader 
LineNumberInputStream 

Zlicza liczb

ę

 wierszy podczas odczytu. 

 

 

 

Podgl

ą

wprzód 

PushbackReader 
PushbackInputStream 

Strumienie wej

ś

ciowe z buforem 

stosowym - umo

Ŝ

liwia podgl

ą

d wprzód. 

 

 

 

Drukowanie 

PrintWriter 
PrintStream 

Zawieraj

ą

 metody dla drukowania.  

 

 

 

Buforowanie 

BufferedReader 
BufferedWriter 
BufferedInputStream 
BufferedOutputStream 

Buforowane strumienie we/wy. 

 
 

 

 

5. Strumienie wej

ś

cia - wyj

ś

cia 

W. Kasprzak: Programowanie zdarzeniowe 

5 - 16 

Filtracja 

FilterReader 
FilterWriter 
FilterInputStream 
FilterOutputStream 

Klasy abstrakcyjne definiuj

ą

ce interfejs 

dla strumieni filtrujacych - 
wzmacniaj

ą

cych odczyt lub zapis. 

 

 

 

Konwersja 
pomi

ę

dzy 

bajtami a 
znakami 

InputStreamReader 
OutputStreamWriter 

InputStreamReader

 - odczytuje bajty z 

InputStream

 i zamienia je na znaki. 

OutputStreamWriter

 - konwertuje znaki 

na bajty i zapisuje je w 

OutputStream

System.getProperty("file.encoding")

 - daje 

domy

ś

lny sposób kodowania znaków. 

Własny system kodowania znaków: 

Kodowanie 16-bitowe znaków odbywa si

ę

 według domy

ś

lnego systemu: 

System.getProperty("file.encoding")

;

 

// Uzyskanie informacji o domy

ś

lnym  

// sposobie kodowania znaków. 

Własny sposób kodowania: 



 utworzy

ć

  obiekt  klasy 

OutputStreamWriter 

pracuj

ą

cy  na  strumieniu 

FileOutputStream

 i poda

ć

 sposób kodowania. 

background image

5. Strumienie wej

ś

cia - wyj

ś

cia 

W. Kasprzak: Programowanie zdarzeniowe 

5 - 17 

3) Strumienie "potokowe - przesyłowe" (

PipedReader, PipedWriter

Niech klasa posiada metody słu

Ŝą

ce do przetwarzania tekstów, takie jak 

sortowanie  słów  i  odwracanie  słów. 

Bez  strumieni  przesyłowych

  wyniki 

po

ś

rednie dla kolejnych wywoła

ń

 tych metod zapisywane musiałyby by

ć

 

w pami

ę

ci programu lub pliku, np.: 

 

 

 
Przy  istnieniu 

strumieni  przesyłowych

  wyj

ś

cie  z  jednej  metody  mo

Ŝ

bezpo

ś

rednio stanowi

ć

 wej

ś

cie dla drugiej metody: 

 

 

 

5. Strumienie wej

ś

cia - wyj

ś

cia 

W. Kasprzak: Programowanie zdarzeniowe 

5 - 18 

Przykład. 

 

U

Ŝ

ycie  klas 

PipedReader

  i 

PipedWriter

  dla  poł

ą

czenia  wej

ś

cia  i  wyj

ś

cia 

pewnych metod 

reverse 

sort

 w celu przetworzenia listy słów. 

 
Mo

Ŝ

liwe b

ę

dzie poł

ą

czone wywołanie obu metod:  

// Utworzenie obiektu strumienia wej

ś

ciowego: 

FileReader words = new FileReader("words.txt");  

// Przetwarzanie potokowe i przekazanie wyniku - obiektu klasy 

Reader:

 

Reader processedWords = reverse(sort(reverse(words))); 

 

W tym celu wymagane s

ą

 odpowiednie definicje 

reverse()

 i 

sort(

). 

Potok

 

W  ka

Ŝ

dej  z  tych  metod  zostan

ą

  utworzone  i  poł

ą

czone  ze  sob

ą

  dwa 

obiekty: (1) obiekt klasy 

PipedReader

 "osadzony" zostaje na (2) obiekcie 

klasy 

PipedWriter

  -  wszystko  to  co  zostanie  zapisane  do  obiektu  klasy 

PipedWriter

 mo

Ŝ

e zosta

ć

 odczytane przez obiekt klasy 

PipedReader

 

background image

5. Strumienie wej

ś

cia - wyj

ś

cia 

W. Kasprzak: Programowanie zdarzeniowe 

5 - 19 

// Definicja metody 

reverse()

 mo

Ŝ

e by

ć

 nast

ę

puj

ą

ca: 

public static Reader reverse(Reader source) throws IOException { 

// Buforuj strumie

ń

 wej

ś

ciowy b

ę

d

ą

cy argumentem metody 

   BufferedReader in = new BufferedReader(source); 

// source 

 in  

// Utwórz i powi

ąŜ

 ze sob

ą

 2 obiekty "potokowe" 

   PipedWriter pipeOut = new PipedWriter(); 

// 1-szy obiekt 

   PipedReader pipeIn = new PipedReader(pipeOut); 

// 2-gi obiekt:  

// pipeOut 

 pipeIn 

// Strumie

ń

 dla wydruku przeka

Ŝ

e dane do 

pipeOut : 

   PrintWriter out = new PrintWriter(pipeOut); 

// out 

 pipeOut 

// Wła

ś

ciwe przetwarzanie odb

ę

dzie si

ę

 w nowym w

ą

tku 

   new ReverseThread(out, in).start(); 

// Wątek do odwracania kolejności: 

// in 

 (odwróć)  out 

   return pipeIn; 

// Metoda zwraca obiekt potokowy 

pipeIn 

typu  

// 

PipedReader 

powi

ą

zany ze stworzonym obiektem 

pipeOut

.  

Metoda 

sort

  jest  prawie  identyczna  z 

reverse

  z  t

ą

  ró

Ŝ

nic

ą

Ŝ

e  tworzy  i 

woła obiekt pewnej klasy 

SortThread

.  

5. Strumienie wej

ś

cia - wyj

ś

cia 

W. Kasprzak: Programowanie zdarzeniowe 

5 - 20 

"Opakowanie" strumienia 

W  powy

Ŝ

szym  przykładzie  metoda 

reverse

  zawiera  m.in.  dwie  dalsze 

instrukcje  powi

ą

zania  obu  obiektów  strumieni  potokowych  z  dalszymi 

strumieniami  (typu 

BufferedReader

  i 

PrintWriter

),  w  celu  skorzystania  z 

dogodnych metod tych klas do odczytu i zapisu wierszy znaków. 

BufferedReader in = new BufferedReader(source); 

// source 

 in 

Nast

ę

puje  tu  otwarcie  strumienia  typu 

BufferedReader

  dla 

ź

ródła,  które 

jest 

strumieniem 

wej

ś

ciowym, 

jednak 

innym 

typie. 

W

ą

tek 

przetwarzaj

ą

cy  czyta  z  obiektu  typu 

BufferedReader

,  który  z  kolei  czyta 

ze 

strumienia 

ź

ródłowego. 

Dzi

ę

ki 

"opakowaniu" 

ź

ródła 

klas

ą

 

BufferedReader

 w

ą

tek mo

Ŝ

e zastosowa

ć

 metod

ę

 

readLine

 tej klasy. 

... 

PrintWriter out = new PrintWriter(pipeOut); 

// out 

 pipeOut  

Podobnie  obiekt  typu 

PipedWriter

  zostaje  opakowany  przez  obiekt  typu 

PrintWriter 

i  program  mo

Ŝ

e  zastosowa

ć

  dogodn

ą

  metod

ę

 

println

  klasy 

PrintWriter

background image

5. Strumienie wej

ś

cia - wyj

ś

cia 

W. Kasprzak: Programowanie zdarzeniowe 

5 - 21 

4) Ł

ą

czenie (konkatenacja) plików (

SequenceInputStream

Przykład.

  U

Ŝ

ycie  klasy 

SequenceInputStream

  dla  poł

ą

czenia  plików  w 

jeden strumie

ń

 odpowiednio do ich kolejno

ś

ci w wywołaniu programu. 

// Klasa główna programu: 

import java.io.*; 
public class PolaczenieStrumieni { 
    public static void main(String[] args) throws IOException { 

// Najpierw tworzony jest obiekt klasy 

ListaPlikow

 o nazwie 

mylist

  

// inicjalizowany list

ą

 plików podan

ą

 w linii wywołania programu.  

// Klasa 

ListPlikow 

musi implementowa

ć

 

interfejs 

Enumeration

, czyli 

// posiada

ć

 m.in. metod

ę

 

nextElement

(). 

        ListaPlikow mylist = new ListaPlikow(args); 

// Konstruktor klasy 

SequenceInputStream 

inicjalizuje obiekt  

// sekwencj

ą

 obiektów typu 

InputStream 

tworzonych wywołaniami  

//metody 

nextElement

 dla obiektu klasy implementuj

ą

cej 

Enumeration 

SequenceInputStream str = new SequenceInputStream(mylist); 
        int bajt; 

5. Strumienie wej

ś

cia - wyj

ś

cia 

W. Kasprzak: Programowanie zdarzeniowe 

5 - 22 

// Metoda 

main

 po utworzeniu obiektu klasy 

SequenceInputStream

,  

// odczytuje z niego bajt po bajcie.  

        while ((bajt = str.read()) != -1)  
                System.out.write( bajt ); 
        str.close(); 
    } 

 

 

Klasa 

ListaPlików

 mo

Ŝ

e by

ć

 zdefiniowana nast

ę

puj

ą

co: 

import java.util.*; 
import java.io.*; 
public class ListPlikow implements Enumeration { 
    private String[] listOfFiles; 
    private int current = 0; 
    public ListPlikow(String[] listOfFiles) { 
        this.listOfFiles = listOfFiles;  
    } 

background image

5. Strumienie wej

ś

cia - wyj

ś

cia 

W. Kasprzak: Programowanie zdarzeniowe 

5 - 23 

    public boolean hasMoreElements() { 
        if (current < listOfFiles.length)    
             return true; 
        else     
             return false; 
    } 

 // Metoda 

nextElement 

klasy 

ListaPlikow

 tworzy strumie

ń

 typu

   

 // FileInputStream 

dla nast

ę

pnej nazwy pliku na li

ś

cie i zwraca ten 

 // obiekt. Je

ś

li lista nazw wyczerpie si

ę

 to zwracane jest 

null

    public Object nextElement() { 

// Zwróci obiekt typu

 FileInputStream

 

        InputStream in = null; 
        if (!hasMoreElements() ) 
            throw new NoSuchElementException("Brak dalszych plików."); 
        else {   
            String nextElement = listOfFiles[current]; 
            current++; 
            try {   
                  in = new FileInputStream(nextElement);

 

5. Strumienie wej

ś

cia - wyj

ś

cia 

W. Kasprzak: Programowanie zdarzeniowe 

5 - 24 

            }  
            catch (FileNotFoundException e) { 
               System.err.println("ListaPlikow:Nie moŜna otworzyć " + 
                                                 nextElement); 
            } 
        } 
        return in; 
    } 

 

background image

5. Strumienie wej

ś

cia - wyj

ś

cia 

W. Kasprzak: Programowanie zdarzeniowe 

5 - 25 

5) Strumienie filtruj

ą

ce 

(FilterInputStream, FilterOutputStream, 

 FilterReader, FilterWriter

Strumie

ń

  filtruj

ą

cy  wymaga  doł

ą

czenia  do  niego  innego  (obrabianego) 

strumienia.  Metoda 

read

  strumienia  filtruj

ą

cego  wczytuje  dane  z 

podległego strumienia, filtruje je i przekazuje jako swój wynik.  
Metoda 

write

  filtruje  przekazywane  jej  dane  i  zapisuje  tak  przetworzone 

dane do podległego strumienia. 
W pakiecie 

java.io

 zdefiniowano bajtowe klasy bazowe 

FilterInputStream

 

FilterOutputStream

 i szereg ich klas pochodnych: 

 

DataInputStream, DataOutputStream 

 

 

BufferedInputStream , BufferedOutputStream  

 

LineNumberInputStream  

 

PushbackInputStream  

 

PrintStream 

(strumie

ń

 wyj

ś

ciowy)

  

W  pakiecie 

java.io

  wyst

ę

puje  jedynie  jedna  klasa  pochodna  od  klasy 

znakowego strumienia 

FilterReader

 :  

PushbackReader

.  

5. Strumienie wej

ś

cia - wyj

ś

cia 

W. Kasprzak: Programowanie zdarzeniowe 

5 - 26 

Utworzenie strumienia filtruj

ą

cego 

Np.  doł

ą

czenie  standardowego  strumienia  wej

ś

ciowego  do  strumienia 

filtruj

ą

cego  i  "opakowanie"  klas

ą

 

BufferedReader

  dla  uzyskania  metody 

readLine()

: 

BufferedReader  d = new BufferedReader (new 
 

 

 

 

 

 

 

 

 DataInputStream(System.in)); 

String input; 
while ((input = d.readLine()) != null) { 
    ... 

// wykonuje przetwarzanie

  

 

Przykład.

  Wykorzystanie  klas 

DataInputStream

  i 

DataOutputStream

 

celu  formatowania  odczytu  i  zapisu  danych  w  postaci  kolumn 
przedzielonych znakiem tabulacji. Kolumnami s

ą

cena, liczba zamówie

ń

opis towaru - zapisane binarnie.  

// (1) Najpierw obiekt typu 

DataOutputStream

 zostaje doł

ą

czony do 

// obiektu klasy 

FileOutputStream

, który słu

Ŝ

y do zapisu do pliku  

// 

rachunek1.txt

:  

background image

5. Strumienie wej

ś

cia - wyj

ś

cia 

W. Kasprzak: Programowanie zdarzeniowe 

5 - 27 

DataOutputStream out = new DataOutputStream
                           new FileOutputStream("rachunek1.txt")); 

// (2) Program korzysta z metody 

write

 klasy 

DataOutputStream

 aby 

// zapisa

ć

 do pliku dane wyst

ę

puj

ą

ce w tablicach odpowiednio  

// do ich typów: 

for (int i = 0; i < prices.length; i ++) { 

// Tablica 

prices 

zawiera dane 

    out.writeDouble(prices[i]);  //  
    out.writeChar('\t'); 
    out.writeInt(units[i]); 
    out.writeChar('\t'); 
    out.writeChars(descs[i]); 
    out.writeChar('\n'); 

out.close(); 

// (3) Teraz otworzymy strumie

ń

 typu 

DataInputStream

 dla wła

ś

nie 

// co zapisanego pliku: 

DataInputStream in = new DataInputStream
                          new FileInputStream("rachunek1.txt")); 

5. Strumienie wej

ś

cia - wyj

ś

cia 

W. Kasprzak: Programowanie zdarzeniowe 

5 - 28 

// (4)

 DataInputStream

 te

Ŝ

 musi by

ć

 doł

ą

czony do innego strumienia - w 

// tym przypadku do 

FileInputStream

 - aby odczyta

ć

 dane z pliku.  

// (5)Teraz dane wczytywane s

ą

 przez specjalizowane metody 

readXxxx 

// klasy 

DataInputStream

try 
 while (true) {

//Teoretycznie bezwarunkowa p

ę

tla ko

ń

czona wyj

ą

tkiem 

        price = in.readDouble(); 
        in.readChar();       

// usuwa znak tabulacji

  

        unit = in.readInt();  
        in.readChar();       

// usuwa znak tabulacji

 

        char chr; 
        desc = new StringBuffer(20); 
        char lineSep = System.getProperty("line.separator").charAt(0); 
        while ((chr = in.readChar() != lineSep) { 
            desc.append(chr); 
        } 
        System.out.println("Zamówiono " + unit +  " jednostek "  
                           + desc + " po cenie $" + price); 

background image

5. Strumienie wej

ś

cia - wyj

ś

cia 

W. Kasprzak: Programowanie zdarzeniowe 

5 - 29 

        total = total + unit * price; 
    }     
}  
catch (EOFException e) { } 
System.out.println("SUMA: $" + total); 
in.close(); 

 

Uwaga:

 zwykle p

ę

tla odczytu danych wygl

ą

da nast

ę

puj

ą

co:   

while ((input = in.read()) != null) { 
    . . . 

Jest  to  mo

Ŝ

liwe  dla  klas,  które  mog

ą

  symbolem 

null

  przekaza

ć

 

osi

ą

gni

ę

cie  ko

ń

ca  pliku.  Wiele  metod  klasy 

DataInputStream

  nie  mo

Ŝ

tak  sygnalizowa

ć

  ko

ń

ca  pliku,  gdy

Ŝ

  ka

Ŝ

da  warto

ść

  mo

Ŝ

e  by

ć

  poprawn

ą

 

dan

ą

,  np.  -1.  Dlatego  te

Ŝ

  metody 

read

  klasy 

DataInputStream

  zgłaszaj

ą

 

w tym celu wyj

ą

tek 

EOFException

.  

5. Strumienie wej

ś

cia - wyj

ś

cia 

W. Kasprzak: Programowanie zdarzeniowe 

5 - 30 

Definiowanie własnych strumieni filtruj

ą

cych 

1.  Utworzy

ć

 klasy pochodne od 

FilterInputStream

 i 

FilterOutputStream

 - 

zwykle współpraca z plikami ma dualny charakter. 

2.  Nadpisa

ć

 metody  

read

  i  

write

 

 w razie potrzeby.  

 

Przykład.

  Zdefiniowanie  pary  klas  pochodnych  od 

FilterInputStream

  i 

FilterOutputStream

 

korzystaj

ą

cych  z  klasy  sprawdzaj

ą

cej  sum

ę

  kontroln

ą

 

odczytywanych i zapisywanych danych. 
Program 

CheckedIODemo

 obejmuje 4 klasy i 1 interfejs: 

 

klasy 

pochodne 

strumieni 

filtruj

ą

cych 

CheckedOutputStream, 

CheckedInputStream  

 interfejs 

Checksum

 i klasa 

Adler32

 dla obliczania sumy kontrolnej, 

 klasa główna programu 

CheckedIODemo

 z metod

ą

 

main

.  

// Konstruktor klasy 

CheckedOutputStream 

public CheckedOutputStream(OutputStream out, Checksum cksum) { 
    super(out);   

// Zainicjalizuj podobiekt dziedziczony

 

    this.cksum = cksum;  

// Zapisz sum

ę

 kontroln

ą

 

background image

5. Strumienie wej

ś

cia - wyj

ś

cia 

W. Kasprzak: Programowanie zdarzeniowe 

5 - 31 

Argumentami 

konstruktora 

s

ą

obiekt 

strumienia 

wyj

ś

ciowego 

OutputStream

 podlegaj

ą

cy filtrowaniu i obiekt klasy 

Checksum

, który jest w 

stanie obliczy

ć

 sum

ę

 kontroln

ą

 

W  klasie 

CheckedOutputStream

  nadpisano  wszystkie  trzy  wersje  metody 

write

 klasy 

FilterOutputStream

:  

public void write(int b) throws IOException { 
    out.write(b); 
    cksum.update(b); 

public void write(byte[] b) throws IOException { 
    out.write(b, 0, b.length); 
    cksum.update(b, 0, b.length); 

public void write(byte[] b, int off, int len) throws IOException { 
    out.write(b, off, len); 
    cksum.update(b, off, len); 

5. Strumienie wej

ś

cia - wyj

ś

cia 

W. Kasprzak: Programowanie zdarzeniowe 

5 - 32 

Celem  metod 

write

  jest  zapis  danych  do  strumienia  wyj

ś

ciowego  i 

modyfikacja sumy kontrolnej. 
 
Klasa 

CheckedInputStream

 jest podobna do klasy 

CheckedOutputStream

.  

Jej jedyny konstruktor to:  

public CheckedInputStream(InputStream in, Checksum cksum) { 
    super(in); 
    this.cksum = cksum; 

W  klasie 

CheckedInputStream

  nadpisano  wszystkie  trzy  wersje  metody 

read

 klasy bazowej 

FilterInputStream

public int read() throws IOException { 
    int b = in.read(); 
    if (b != -1) {   
        cksum.update(b);  
    } 
    return b; 

background image

5. Strumienie wej

ś

cia - wyj

ś

cia 

W. Kasprzak: Programowanie zdarzeniowe 

5 - 33 

public int read(byte[] b) throws IOException { 
    int len; 
    len = in.read(b, 0, b.length); 
    if (len != -1) {  cksum.update(b, 0, b.length); } 
    return len; 

public int read(byte[] b, int off, int len) throws IOException { 
    len = in.read(b, off, len); 
    if (len != -1) {   cksum.update(b, off, len); } 
    return len; 

Metody 

read

  wczytuj

ą

  dane  ze  strumienia  wej

ś

ciowego  i  je

ś

li  wczytano 

dan

ą

 to nast

ą

pi modyfikacja sumy kontrolnej. 

Interfejs 

Checksum

  obejmuje  m.in.  metody 

getValue

  i 

update 

przeznaczone  dla  pobrania  i  modyfikowania  warto

ś

ci  sumy  kontrolnej. 

Suma  jest  obliczana  krok  po  kroku  dla  danych  całego  strumienia.  Np. 
klasa 

Adler32

 implementuje ten interfejs. 

 

5. Strumienie wej

ś

cia - wyj

ś

cia 

W. Kasprzak: Programowanie zdarzeniowe 

5 - 34 

Klasa główna programu 

CheckedIODemo

import java.io.*; 
public class CheckedIODemo { 
    public static void main(String[] args) throws IOException { 
       Adler32 inChecker = new Adler32(); 
       Adler32 outChecker = new Adler32(); 
       CheckedInputStream in = null; 
       CheckedOutputStream out = null; 
       try {  in = new CheckedInputStream( 
   

 

   new FileInputStream("plikWE.txt"),  inChecker); 

                out = new CheckedOutputStream( 
   

 

    new FileOutputStream("plikWY.txt"),  outChecker); 

       } catch (FileNotFoundException e) { 
           System.err.println("CheckedIODemo: " + e); 
           System.exit(-1); 
       } catch (IOException e) { 
           System.err.println("CheckedIODemo: " + e); 
           System.exit(-1); 

background image

5. Strumienie wej

ś

cia - wyj

ś

cia 

W. Kasprzak: Programowanie zdarzeniowe 

5 - 35 

       } 
       int c; 
       while ((c = in.read()) != -1)          

                

out.write(c); 

       System.out.println("Suma kontrolna WE: " + inChecker.getValue()); 
       System.out.println("Suma kontrolna WY: "+ outChecker.getValue()); 
       in.close(); 
       out.close(); 
    } 

W  metodzie 

main

  utworzono  dwa  obiekty  klasy 

Adler32

  dla  obliczania 

sumy  kontrolnej  dwóch  obiektów  klas 

CheckedOutputStream

  i 

CheckedInputStream

,  które  otwarte  zostaj

ą

  dla  dwóch  plików.  Pierwszy 

obiekt wczytuje dane z 1-szego pliku a drugi zapisuje je w drugim pliku - 
oba  wykorzystuj

ą

  przy  tym  swoje  obiekty  klasy 

Adler32

  w  celu 

modyfikacji sumy kontrolnej. 

5. Strumienie wej

ś

cia - wyj

ś

cia 

W. Kasprzak: Programowanie zdarzeniowe 

5 - 36 

5.3 

Serializacja 

obiektu 

(klasy 

ObjectInputStream, 

ObjectOutputStream 

Klasy  bajtowych  strumieni 

ObjectInputStream

 

ObjectOutputStream

 

umo

Ŝ

liwiaj

ą

  zapis  i  odczyt  trwałego  obiektu,  w  tym  serializacj

ę

  i 

deserializacj

ę

 obiektu.  

 

Zastosowanie serializacji



 Dla 

"Remote  Method  Invocation"

  (RMI)  -  komunikacja  obiektów  poprzez 

gniazdka - przekazywanie obiektu pomi

ę

dzy klientem i serwerem



 Trwało

ść

  obiektu  w  aplikacji  -  archiwizacja  obiektu  umo

Ŝ

liwi  jego 

odtworzenie po ponownym wywołaniu programu. 

 
Klasa  obiektu  podlegaj

ą

cego  serializacji  musi  implementowa

ć

  interfejs 

Serializable

 

background image

5. Strumienie wej

ś

cia - wyj

ś

cia 

W. Kasprzak: Programowanie zdarzeniowe 

5 - 37 

1) Mechanizmy serializacji obiektów  

Zapis obiektu do strumienia (

ObjectOutputStream)

 

Np. 

FileOutputStream out = new FileOutputStream("Czas.txt"); 
ObjectOutputStream s = new ObjectOutputStream(out); 

//Nasz obiekt 

s.writeObject("Dzisiaj");  

// Serializacja napisu

 

s.writeObjectnew Date()); 

// Serializacja obiektu klasy

 

s.flush(); 

Obiekt  klasy 

ObjectOutputStream

  tworzony  jest  na  obiekcie  innej  klasy 

strumieniowej,  np. 

FileOutputStream

  (dla  pliku  "Czas.txt"  w  powy

Ŝ

szym 

przykładzie).  Metoda 

writeObject

  zapisuje  do  pliku  zarówno  napis  jak  i 

obiekt klasy 

Date

 

ObjectOutputStream

  implementuje  interfejs 

DataOutput

  -  s

ą

  tu  metody 

dla zapisu elementarnych typów danych: 

writeInt, writeFloat, writeUTF

.  

 

Metoda 

writeObject

  zgłasza  wyj

ą

tek 

NotSerializableException

  je

ś

li  nie 

mo

Ŝ

e dokona

ć

 serializacji przekazanego jej obiektu. 

5. Strumienie wej

ś

cia - wyj

ś

cia 

W. Kasprzak: Programowanie zdarzeniowe 

5 - 38 

Odczyt obiektu ze strumienia (

ObjectInputStream)

 

Np. 

FileInputStream in = new FileInputStream("Czas"); 
ObjectInputStream s = new ObjectInputStream(in); 

// Nasz obiekt 

String today = (String)s.readObject(); 

// Deserializuj napis 

Date date = (Date)s.readObject(); 

// Deserializauj obiekt 

 

Obiekt  klasy 

ObjectInputStream

  konstruowany  jest  na  obiekcie  innej 

klasie strumieniowej - w podanym przypadku jest ni

ą

 

FileInputStream

.  

Metoda 

readObject

 pozwala na wczytanie obiektu, np. typu 

String

 i 

Date

 z 

pliku. 

Zwraca 

ona 

referencj

ę

 

typu 

Object

która 

musi 

by

ć

 

przekonwertowana na wła

ś

ciwy typ referencji. 

 

ObjectInputStream

  implementuje  interfejs 

DataInput

  wyznaczaj

ą

cy 

metody  dla  odczytu  elementarnych  typów  danych,  jak  np. 

readInt, 

readFloat, readUTF

.  

 

Deserializacj

ę

  obiektu  zapewnia  metoda 

defaultReadObject

  w  klasie 

ObjectInputStream

.  

background image

5. Strumienie wej

ś

cia - wyj

ś

cia 

W. Kasprzak: Programowanie zdarzeniowe 

5 - 39 

2) Zapewnienie standardowej serializacji obiektu w naszej klasie 

Obiekt  mo

Ŝ

e  zosta

ć

  serializowany  tylko  wtedy,  gdy  jego  klasa 

implementuje interfejs 

Serializable

 (ale jest to PUSTY interfejs): 

package java.io; 
public interface Serializable { 

// Jest to pusty interfejs przeznaczony dla 

// zaznaczania klas, dla których zdefiniowano serializacj

ę

.

  

}; 

Wykorzystanie - deklarowanie implementowania interfejsu: 

public class MojaSerializowalnaKlasa implements Serializable { 
    ... 

ale bez konieczno

ś

ci implementacji jakie

ś

 metody.  

Zadanie 

serializacji 

obiektów 

takiej 

klasy 

przejmie 

metoda 

defaultWriteObject

  w  klasie 

ObjectOutputStream

.  Wypisuje  ona 

automatycznie nast

ę

puj

ą

ce dane potrzebne do odtworzenia obiektu: 

 klas

ę

 obiektu, sygnatur

ę

 klasy, warto

ś

ci wszystkich nie przechodnich i 

niestatycznych pól, w tym warto

ś

ci referencji do innych obiektów.  

5. Strumienie wej

ś

cia - wyj

ś

cia 

W. Kasprzak: Programowanie zdarzeniowe 

5 - 40 

3) Indywidualny sposób serializacji obiektu 

 Własna  obsługa  serializacji  i  deserializacji  obiektu  jest  mo

Ŝ

liwa  po 

zdefiniowaniu  metod 

writeObject

  i 

readObject

.  Ich  rola  polega  na 

przekazaniu dodatkowej informacji o obiekcie do lub ze strumienia. 

 Metoda 

writeObject

  musi  woła

ć

  domy

ś

ln

ą

  metod

ę

  serializacji 

defaultWriteObject

 danego strumienia swoj

ą

 pierwsz

ą

 instrukcj

ą

private void writeObject(ObjectOutputStream s) throws IOException { 
    s.defaultWriteObject(); 

    // Własny kod serializacji ...  

 Metoda 

readObject

  powinna  wczytywa

ć

  wszystko  to  co  zapisano 

metod

ą

  

writeObject

. Jej struktura: 

private void readObject(ObjectInputStream s) throws IOException  { 
    s.defaultReadObject(); 

    // Własna deserializacja obiektu ... 

    ... 

    // Ewentualnie wykorzystanie informacji dla modyfikacji obiektu

  

...  

background image

5. Strumienie wej

ś

cia - wyj

ś

cia 

W. Kasprzak: Programowanie zdarzeniowe 

5 - 41 

Implementacja interfejsu 

Externalizable

 

Aby  uzyska

ć

  wył

ą

czn

ą

  odpowiedzialno

ść

  naszej  klasy  za  serializacj

ę

  jej 

obiektów nale

Ŝ

y zaimplementowa

ć

 interfejs 

Externalizable

 . 

Dla  obiektów  typu 

Externalizable

  automatycznie  zapisywana  jest  jedynie 

identyfikacja  klasy

.  Klasa  odpowiada  za  zapis  i  odczyt  zawarto

ś

ci  jej  obiektu  i 

za koordynacj

ę

 w tej sprawie ze swoj

ą

 klas

ą

 bazow

ą

package java.io; 
public interface Externalizable extends Serializable { 
    public void writeExternal(ObjectOutput out) throws IOException; 
    public void readExternal(ObjectInput in) throws IOException,  
                             java.lang.ClassNotFoundException; 

Klasa  typu 

Externalizable

  musi  zaimplementowa

ć

  metody  publiczne 

writeExternal

 i 

readExternal

.  

Wi

ąŜ

e  si

ę

  to  z  ryzykiem  uzyskania  bezpo

ś

redniego  dost

ę

pu  przez  program 

klienta  do  zasobów  obiektu  tej  klasy.  Dlatego  mo

Ŝ

na  tak  post

ą

pi

ć

  jedynie  z 

klasami  nie  zawieraj

ą

cymi  informacji  zabezpieczonej  lub  krytycznej  dla 

zachowania si

ę

 programu. 

5. Strumienie wej

ś

cia - wyj

ś

cia 

W. Kasprzak: Programowanie zdarzeniowe 

5 - 42 

Ochrona wra

Ŝ

liwej informacji 

 
1)  Pola  zawieraj

ą

ce 

wra

Ŝ

liwe 

dla  systemu  dane  oznaczane  s

ą

  jako 

private  transient

Pola  typu 

transient

  i 

static

  nie  podlegaj

ą

 

serializacji / deserializacji.  

2) 

Cało

ś

ciowo "wra

Ŝ

liwe" klasy

 w ogóle nie powinny by

ć

 serializowane 

- nie nale

Ŝ

y implementowa

ć

 

Serializable

 lub 

Externalizable

.  

3)  Mo

Ŝ

na  w  metodach 

writeObject

  i 

readObject

 

weryfikowa

ć

 

poprawno

ść

 stanu obiektu 

i w razie bł

ę

dnego stanu 

zgłosi

ć

 wyj

ą

tek

 

NotSerializableException

, co uchroni program przed korzystaniem z 

obiektu. 

background image

5. Strumienie wej

ś

cia - wyj

ś

cia 

W. Kasprzak: Programowanie zdarzeniowe 

5 - 43 

5.4 Współpraca z plikami o dost

ę

pie swobodnym 

Strumienie znakowe i bajtowe posiadaj

ą

 sekwencyjny dost

ę

p.  

Inaczej jest z klas

ą

 

RandomAccessFile

, która umo

Ŝ

liwia swobodny dost

ę

do elementów pliku.  
 
Mo

Ŝ

liwe  jest  te

Ŝ

  zdefiniowanie  nad  tym  strumieniem  strumieni 

filtruj

ą

cych, tzn. implementuj

ą

cych interfejsy 

DataInput

 

DataOutput

.  

 

Np.

 ZIP jest to format archiwizacji plików. Dost

ę

p sekwencyjny do takiego 

pliku  wymaga  przeczytania  du

Ŝ

ej  cz

ęś

ci  pliku  zanim  dotrzemy  do 

katalogu zawieraj

ą

cego informacj

ę

 o interesuj

ą

cych nas plikach.  

W  przypadku 

swobodnego  dost

ę

pu

  wykorzystamy  metod

ę

 

seek

  w  celu 

przeszukania pliku (bez konieczno

ś

ci odczytu) i dotarcia do katalogu. 

 

Utworzenie  obiektu

  tej  klasy 

RandomAccessFile

  wymaga  przekazania 

nazwy pliku lub obiektu klasy 

File

 oraz sposobu współpracy z plikiem.  

Np. 

5. Strumienie wej

ś

cia - wyj

ś

cia 

W. Kasprzak: Programowanie zdarzeniowe 

5 - 44 

new RandomAccessFile("plikWE.txt", "r");

 // Otwarcie dla odczytu 

new RandomAccessFile("plikWEWY.txt", "rw");

 // Odczyt i zapis 

 
Klasa 

RandomAccessFile

 

słu

Ŝ

y zarówno do odczytu jak i zapisu do pliku. 

 

Nie dziedziczy

 ona z 

InputStream

 

ani z 

OutputStream

.  

 Jednak 

implementuje

  interfejsy 

DataInput

  i 

DataOutput

  co  umo

Ŝ

liwia 

zastosowanie do niej strumieni filtruj

ą

cych. 

Operowanie na pliku odbywa si

ę

 za pomoc

ą

 metod wyznaczonych przez 

interfejsy 

DataInput

 

DataOutput

.  

 

Wska

ź

nik  pliku

  -  wskazuje  aktualn

ą

  pozycj

ę

  w  pliku,  od  0  do  liczby 

bajtów.  Wska

ź

nik  przesuwany  jest  odpowiednio  do  liczby  bajtów  dla 

operacji odczytu lub zapisu.  
S

ą

 te

Ŝ

 metody jawnej modyfikacji wska

ź

nika pliku: 



 

int skipBytes(int)

 - przesu

ń

 wska

ź

nik wprzód o okre

ś

lon

ą

 liczb

ę

 bajtów. 



 

void seek(long)

 

- umie

ść

 wska

ź

nik bezpo

ś

rednio przez zadanym bajtem. 



 

long getFilePointer()

 - zwró

ć

 poło

Ŝ

enie wska

ź

nika wyra

Ŝ

one w bajtach. 

 

background image

5. Strumienie wej

ś

cia - wyj

ś

cia 

W. Kasprzak: Programowanie zdarzeniowe 

5 - 45 

Tworzenie strumieni filtruj

ą

cych dla plików o swobodnym dost

ę

pie 

 

Przykład.

  Powrócimy  do  przykładu  z 

CheckedIODemo

.

  Jednak  teraz 

utworzymy strumienie filtruj

ą

ce dla klasy 

RandomAccessFile

.  

 

(1)  Teraz  klasa 

CheckedDataOutput

 

jest  modyfikacj

ą

  poprzedniej  klasy 

CheckedOutputStream

  -  oblicza  sum

ę

  kontroln

ą

  danych  zapisywanych  do 

strumienia. Jednak operuje na obiektach implementuj

ą

cych 

DataOutput

 a 

nie na obiektach klasy 

OutputStream

(2)  Klasa 

CheckedDataInput

 

jest  modyfikacj

ą

  klasy 

CheckedInputStream

pracuj

ą

c

ą

 na obiektach 

DataInput

 zamiast 

InputStream

.  

 

(3) Ró

Ŝ

nice mi

ę

dzy 

CheckedDataOutpu

t

 a 

CheckedOutputStream:

 

(I) 

CheckedDataOutput

 nie dziedziczy po 

FilterOutputStream

 a implementuje 

interfejs 

DataOutput

:  

public class CheckedDataOutput implements DataOutput { ... 

(II)  W 

CheckedDataOutput

  zadeklarowano  prywatne  pole  -  obiekt  typu 

DataOutput

do którego zapisywane b

ę

d

ą

 dane.

 

private DataOutput out; 

5. Strumienie wej

ś

cia - wyj

ś

cia 

W. Kasprzak: Programowanie zdarzeniowe 

5 - 46 

 

(III)  Konstruktor  klasy 

CheckedDataOutput

  tworzy  obiekt  "osadzony"  na 

obiekcie  

DataOutput

 

 a nie na 

OutputStream

.  

public CheckedDataOutput(DataOutput out, Checksum cksum) { 
    this.cksum = cksum; 
    this.out = out; 

(IV)  Konstruktor  nie  woła 

super(out)

  jak  w 

CheckedOutputStream

,

  gdy

Ŝ

 

klasa dziedziczy z klasy 

Object

 a nie klasy strumieniowej. 

 

(4) Podobnych zmian dokonano w 

CheckedDataInput

:  

(I) 

CheckedDataInput

 

implementuje 

DataInput

.  

(II)  W 

CheckedDataInput

  zadeklarowano  prywatne  pole  typu 

DataInput

 

na którym osadzono obiekt tej klasy.  
(III) Konstruktor w 

CheckedDataInput

 

wymaga obiektu 

DataInput

.  

 

(5)  Równie

Ŝ

  metody 

readXxxx

  w  klasie 

CheckedDataInput

  posiadaj

ą

 

zmienione nazwy i sygnatury: 

public byte readByte() throws IOException { 

background image

5. Strumienie wej

ś

cia - wyj

ś

cia 

W. Kasprzak: Programowanie zdarzeniowe 

5 - 47 

    byte b = in.readByte(); 
    cksum.update(b); 
    return b; 

public void readFully(byte[] b) throws IOException { 
    in.readFully(b, 0, b.length); 
    cksum.update(b, 0, b.length); 

public void readFully(byte[] b, int off, int len) throws IOException { 
    in.readFully(b, off, len); 
    cksum.update(b, off, len); 

(6) Mamy teraz dwa programy testuj

ą

ce: 



 poprzedni

 

CheckedDIODemo

,  sprawdzał  działanie  filtrów  na  plikach  o 

sekwencyjnym dost

ę

pie (

DataInputStream

 i 

DataOutputStream

).  



 nowy 

CheckedRAFDemo

,  sprawdza  filtry  dla  plików  o  swobodnym 

dost

ę

pie (

RandomAccessFile

)  

 

5. Strumienie wej

ś

cia - wyj

ś

cia 

W. Kasprzak: Programowanie zdarzeniowe 

5 - 48 

Jedyna ró

Ŝ

nica mi

ę

dzy nimi polega na typie otwieranych obiektów.  

CheckedDIODemo

in = new 

CheckedDataInput

(new DataInputStream

         new FileInputStream("plikWE.txt")), inChecker); 
out = new 

CheckedDataOutput

(new DataOutputStream

          new FileOutputStream("plikWY.txt")), outChecker); 

CheckedRAFDemo

:

 

in = new 

CheckedDataInput

         new RandomAccessFile("plikWE.txt", "r"), inChecker); 
out = new 

CheckedDataOutput

          new RandomAccessFile("plikWY.txt", "rw"), outChecker); 

background image

5. Strumienie wej

ś

cia - wyj

ś

cia 

W. Kasprzak: Programowanie zdarzeniowe 

5 - 49 

5.5 Pozostałe klasy w java.io 

Poza omawianymi klasami 

w pakiecie 

java.io

 wyst

ę

puj

ą

 klasy i interfejsy: 

File  

Reprezentuje  plik  nale

Ŝą

cy  do  rodzimego  systemu  plików.  Mo

Ŝ

na 

utworzy

ć

 obiekt klasy 

File 

dla pliku. 

 

FileDescriptor  

Reprezentuje uchwyt (lub deskryptor) do otwartego pliku lub gniazdka. 
Ta klasa zwykle nie jest u

Ŝ

ywana przez programist

ę

 u

Ŝ

ytkowego. 

 

StreamTokenizer  

Rozdziela  strumie

ń

  na  "token-y"  -  elementarne  jednostki  dla  parsera 

tekstu (słowo, symbol) . 
 

FilenameFilter  

Korzysta  z  niej  metoda 

list

  w  klasie 

File

  dla  okre

ś

lenia,  które  pliki  w 

kartotece maj

ą

 by

ć

 wybrane. 

5. Strumienie wej

ś

cia - wyj

ś

cia 

W. Kasprzak: Programowanie zdarzeniowe 

5 - 50 

 

Strumienie WE-WY w pakiecie 

java.util.zip

 

 

CheckedInputStream , CheckedOutputStream  

Para 

strumieni 

realizuj

ą

ca 

sprawdzanie 

sumy 

kontrolnej 

dla 

wczytywanych lub wysyłanych danych. 
 

DeflaterOutputStream, InflaterInputStream  

Para strumieni do kompresji i dekompresji danych.  
 

GZIPInputStream, GZIPOutputStream  

Dla odczytu i zapisu komprymowanych danych w formacie GZIP.  
 

ZipInputStream, ZipOutputStream  

Dla odczytu i zapisu komprymowanych danych w formacie ZIP.