background image

Paweł Tokarczyk 

Piotr Mlekodaj

OPERACJE I/O W JAVA

background image

Obsługa  operacji  wejścia-wyjścia  (we/wy,  IO,  input-output)  wiąże 
się  z 

szeroką  tematyką  pobierania  danych  do  naszych  aplikacji  ze 

źródeł 

zewnętrznych  (w  tym  z  interakcją  z  użytkownikiem)  i 

zwracaniem 

danych na zewnątrz (np. zapisywaniem do pliku).

Większość klas Java związanych z operacjami IO znajduje się w 

pakiecie  java.io.  W  Javie  operacje  I/O  realizuje  się  za  pomocą 
strumieni.

WEJŚCIE I WYJŚCIE

Strumień  oznacza  tor  komunikacyjny  między  dowolnym  źródłem 
danych  zdolnym 

do  produkcji  porcji  danych  a  ich  odbiornikiem 

zdolnym  do  przyjmowania  porcji  danych.  Na  strumieniach  możemy 
wykonywać  dwie  podstawowe  operacje:  odczytywanie  danych  i 
zapisywanie danych.

background image

STRUMIENIE - PODZIAŁ

Strumienie możemy podzielić na:

• Wejściowe klasy strumieni wejściowych

• Wyjściowe

klasy strumieni wyjściowych

W Javie – ze względu na przyjęcie standardu kodowania znaków (Unikod) 
– wyróżnia się również inny „atom danych” – znak Unikodu, złożony z 
dwóch  bajtów.  Wobec  tego  powstają  kolejne  dwie  rozłączne  hierarchie 
klas strumieniowych:

• klasy strumieni  bajtowych(„atomem” operacji we-wy jest 

bajt, Bytestream)

• klasy strumieni znakowych („atomem” są znaki Unikodu – 2 

bajty, Characterstream).

Przy  przetwarzaniu  tekstów  należy  korzystać  ze  strumieni  znakowych  ze 
względu  na  to,  iż w trakcie czytania/pisania  wykonywane  są odpowiednie 
operacje  kodowania/dekodowania  ze  względu  na  stronę  kodową  właściwą 
dla źródła/odbiornika

background image

Wejście

Wyjście

Strumienie bajtowe

InputStream

OutputStream

Strumienie znakowe

Reader

Writer

HIERARCHIE KLAS 

STRUMIENIOWYCH

Są  to  klasy  abstrakcyjne,  zatem  bezpośrednio  nie  można  tworzyć 
obiektów 

tych 

klas. 

Dostarczają  one   natomiast  podstaw  dla  wszystkich  innych  klas 
strumieniowych  oraz  paru  ogólnych  użytecznych  (choć   bardzo 
podstawowych)  metod. 

• read(..)  (bajtów, znaków) - pozwala na przeczytanie jednego bajtu ze 

strumienia bajtowego lub znaku ze strumienia znakowego albo całej 
porcji bajtów/znaków,  

• write(...)(bajtów/znaków) - pozwala zapisywać pojedyncze bajty/znaki 

lub tablice bajtów/znaków, a w przypadku strumieni znakowych również 
napisy (obiekty klasy String),

• metody skip(..)mark(..)reset() ) - każdy strumień może być 

traktowany jako sekwencja bajtów/znaków, czytanie i zapisywanie 
zawsze dotyczy bieżącej pozycji tej sekwencji; po wykonaniu operacji 
czytania lub zapisu bieżąca pozycja zwiększa się o jeden; metody 
pozycjonowania pozwalają zmieniać bieżącą pozycję.

•  close())- strumień zawsze należy zamknąć po zakończeniu operacji na 

nim.

background image

STRUMIENIE - BINARNE

background image

METODY INPUTSTREAM

background image

METODY OUTPUTSTREAM

background image

KLASA FILE

Operacje plikowe wykonuje się za pomocą metod klasy File.

.

background image

Strumień wyjściowy do zapisu:

FileOutputStream out = new FileOutputStream ("nazwa.dat„);

Jeżeli chcemy dopisać bajty do istniejącego już pliku:

FileOutputStream out = new FileOutputStream("nazwa.dat", true);

out.write(x); //x – int od 0 do 255

out.Close();

Odczyt bajtów ze strumienia i pobranie danych:

FileInputStream in = new FileInputStream("a.dat");

while(true){

int x = in.read();

if(x == -1)

break;

System.out.print(x + " "); 

}

in.Close();

STRUMIENIE PLIKOWE

background image

PRZYKŁADY W 

ŚRODOWISKU ECLIPSE:

-  

ByteRade

r

-  

ByteWrite

r

background image

STRUMIENIE BUFOROWANE

Buforowanie  ogranicza  liczbę  fizycznych  odwołań  do  urządzeń 
zewnętrznych,  dzięki temu, że fizyczny odczyt lub zapis dotyczy całych 
porcji  danych,  gromadzonych  w  buforze  (wydzielonym  obszarze 
pamięci). Jedno 

fizyczne odwołanie wczytuje dane ze strumienia do 

bufora  lub  zapisuje 

zawartość  bufora  do  strumienia.  W  naszym 

programie operacje czytania  lub pisania dotyczą w większości bufora 
(dopóki  są  w  nim  dane  lub  dopóki  jest  miejsce  na  dane)  i  tylko 
niekiedy   powodują  fizyczny 

odczyt (gdy  bufor  jest  pusty)  lub  zapis 

(gdy bufor jest pełny).

FileOutputStream out = new FileOutputStream("a.dat");
FileInputStream in = new FileInputStream("a.dat");

Deklaracja bufora i łączenie ze strumieniem:

BufferedOutputStream buffOut =new 
BufferedOutputStream(out);
BufferedInputStream buffIn =new BufferedInputStream(in);

Operacje wykonujemy na buforze:

buffOut.write(127);
buffOut.close();
int x = buffIn.read();
buffIn.close();

background image

STRUMIENIE DANYCH

Strumienie danych umozliwiaja posługiwanie sie
róznymi typami danych. Filtruja one połaczone z
nimi strumienie bajtów, pozwalajac na zapis i
odczyt prostych typów danych.

Podstawowe klasy to:
DataOutputStream,
DataInputStream.

background image

STRUMIENIE DANYCH

Tworzenie wyjściowego strumienia danych
przebiega według poniższego schematu.
Deklarujemy strumień plikowy i łączymy go z
plikiem:

FileOutputStream out =

new FileOutputStream("a.dat");

Deklarujemy bufor i łączymy go ze strumieniem:

BufferedOutputStream buffOut =

new BufferedOutputStream(out);

background image

STRUMIENIE DANYCH

Deklarujemy strumień danych i łączymy go z
buforem:

DataOutputStream data =

new DataOutputStream(buffOut);

Zapisujemy dane do strumienia danych:

data.writeDouble(12.5);

background image

STRUMIENIE DANYCH

Ponownie, możliwe jest wygodne skrócenie
zapisu:
DataOutputStream data =

new DataOutputStream(

new BufferedOutputStream(

new FileOutputStream("a.dat")));

background image

METODY STRUMIENI DANYCH

background image

ZAPIS PROSTYCH TYPÓW OD 

STRUMIENIA

import java.io.*;
public class WriteStream
{

public static void main(String[] args)
{
double[] v = {0.0, 1.2, 9.1, 2.5, 3.6, 12.4, 5.5};

try
{

DataOutputStream data =

new DataOutputStream(

new BufferedOutputStream(

new FileOutputStream("C:\\a.dat")););

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

data.writeDouble(v[i]);

data.close();
}

     catch(IOException exc) { exc.printStackTrace(); }
       }
}

background image

ODCZYT PROSTYCH TYPÓW OD 

STRUMIENIA

import java.io.*;
public class ReadStream
{

public static void main(String[] args)
{
     try
     {
DataInputStream data =

new DataInputStream(

new BufferedInputStream(

new FileInputStream("C:\\a.dat")));

    try
      {
 while(true)
    {

double x = data.readDouble();
System.out.print(x + " ");

      }

    

 }
catch(EOFException exc) { data.close(); }

  

 }
catch(IOException exc) { exc.printStackTrace(); }

          }
}

background image

ODCZYT PROSTYCH TYPÓW OD 

STRUMIENIA

Użyta w powyższym przykładzie metoda
readDouble() nie zwraca żadnej wartości, która
wskazywałaby na osiągniecie końca pliku.
Wykorzystujemy wiec fakt, ze po napotkaniu
końca pliku wystąpi wyjątek IOException.

background image

STRUMIENIE ZNAKOWE

Reader i Writer to klasy bazowe strumieni
znakowych. Służą one do przesyłania znaków
Unicode o 16-bitowych kodach.

Wszystkie znakowe operacje wejścia-wyjścia
powinny być wykonywane na strumieniach
znakowych, które poprawnie obsługują znaki
Unikodu, np. FileWriter i BufferedWriter.

background image

STRUMIENIE ZNAKOWE

Deklarujemy strumien plikowy i łaczymy go z
plikiem:

FileWriter writer =

new FileWriter("a.dat");

Deklarujemy bufor i łaczymy go ze strumieniem:

BufferedWriter buff =

new BufferedWriter(f);

Umieszczamy dane w strumieniu buforowanym:

buff.write('A');

Zamykamy strumien buforowany:

buff.close();

background image

KLASY STRUMIENI ZNAKOWYCH

background image

METODY KLASY READER 

background image

METODY KLASY WRITER


Document Outline