Strumienie

Strumienie reprezentują w programie rozmaite źródła danych, zarówno

wejściowe (WE) jak i wyjściowe (WY).

Źródłami danych mogą być:

• pliki dyskowe,

• urządzenia wejścia-wyjścia (np. drukarka, karta sieciowa),

• inne programy,

• tablice.

Strumienie reprezentują dane w rozmaitej postaci – mogą to być bajty,

znaki, inne typy proste (np. int, double) lub nawet obiekty o złożonej

strukturze.

Innymi słowy, strumień jest sekwencją danych – bajtów, znaków, typów

prostych lub obiektów.

Strumienie mogą jedynie transportować dane lub modyfikować je na

różne sposoby,

Podstawy programowania

Materiały do użytku wewnętrznego

9.1

Czytanie i pisanie danych

Strumień danych wejściowych

Pogram

Źródło

00110100

10010100

00110000

danych

Strumień danych wyściowych

Pogram

Źródło

00110100

10010100

00110000

danych

Podstawy programowania

Materiały do użytku wewnętrznego

9.2

Strumień bajtów

Strumienie bajtów stosowane są wówwczas, gdy zachodzi potrzeba

manipulowania danymi o surowej, numerycznej postaci zero-jedynkowej.

Wszystkie klasy używane do obsługi strumieni bajtów wywodzą się z

dwóch klas podstawowych: InputStream i OutputStream, odpowiednio do czytania i pisania danych. Są to klasy abstrakcyjne.

Podstawowymi klasami używanymi do manipulowania strumieniami

bajtów są klasy FileInputStream oraz FileOutputStream.

Podstawy programowania

Materiały do użytku wewnętrznego

9.3

Strumień bajtów - pisanie

import java.io.FileOutputStream;

import java.io.IOException;

public class ByteStreamPisanie

{

public static void main( String[] args ) throws IOException

{

int [] punkty = { 70, 43, 74, 2, 29, 10, 82, 92, 2, 17 };

FileOutputStream pisanie = null;

try

{

pisanie = new FileOutputStream( "liczby.bin" );

for( int k = 0; k < punkty.length; k++ )

pisanie.write( punkty[ k ] );

}

finally

{

if ( pisanie != null ) pisanie.close();

}

}

}

Podstawy programowania

Materiały do użytku wewnętrznego

9.4

Strumień bajtów - czytanie

import java.io.FileInputStream;

import java.io.IOException;

public class ByteStreamCzytanie

{

public static void main(String[] args) throws IOException

{

FileInputStream czytanie = null;

int liczba;

try

{

czytanie = new FileInputStream( "liczby.bin" );

while ( ( liczba = czytanie.read() ) != -1 )

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

}

finally

{

if ( czytanie != null ) czytanie.close();

}

}

}

// 70 43 74 2 29 10 82 92 2 17

Podstawy programowania

Materiały do użytku wewnętrznego

9.5

Strumień bajtów - kopiowanie

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.IOException;

public class ByteStreamKopiowanie

{

public static void main(String[] args) throws IOException

{

FileInputStream czytanie = null;

FileOutputStream pisanie = null;

try {

czytanie = new FileInputStream( "liczby.bin" );

pisanie = new FileOutputStream( "liczby-kopia.bin" );

int liczba;

while ( ( liczba = czytanie.read()) != -1 ) pisanie.write( liczba );

}

finally {

if ( czytanie != null ) czytanie.close();

if ( pisanie != null ) pisanie.close();

}

}

}

Podstawy programowania

Materiały do użytku wewnętrznego

9.6

Strumienie znaków

Zmienne znakowe (typ char) reprezentowane są w pamięci operacyjnej w

konwencji Unicode (1 znak – dwa bajty).

Strumienie znakowe automatycznie dokonują translacji znaków z

wewnętrzenej reprezentacji języka Java do reprezentacji wymaganej

przez system operacyjny.

Wszystkie klasy używane do obsługi strumieni znaków wywodzą się z

dwóch klas podstawowych: Reader i Writer, odpowiednio do czytania i pisania danych. Są to klasy abstrakcyjne.

Podstawowymi klasami używanymi do manipulowania strumieniami

znaków są klasy FileReader oraz FileWriter.

Podstawy programowania

Materiały do użytku wewnętrznego

9.7

Strumień znaków - pisanie

import java.io.FileWriter;

import java.io.IOException;

public class CharStreamPisanie

{

public static void main( String[] args ) throws IOException

{

String loremIpsum =

"Lorem ipsum dolor sit amet, consectetuer adipiscing elit.\n" +

"Nullam feugiat, turpis at pulvinar vulputate, erat libero\n" +

"tristique tellus, nec bibendum odio risus sit amet ante.";

FileWriter pisanie = null;

try

{

pisanie = new FileWriter( "znaki.txt" );

for ( int k = 0; k < loremIpsum.length(); k++ )

pisanie.write( loremIpsum.charAt( k ) );

}

finally

{

if ( pisanie != null ) pisanie.close();

}

}

}

Podstawy programowania

Materiały do użytku wewnętrznego

9.8

Strumień znaków - czytanie

import java.io.FileReader;

import java.io.IOException;

public class CharStreamCzytanie

{

public static void main(String[] args) throws IOException

{

String loremIpsum = "";

FileReader czytanie = null;

try

{

czytanie = new FileReader( "znaki.txt" );

int znak;

while ( ( znak = czytanie.read() ) != -1 ) loremIpsum += (char)znak;

}

finally

{

if ( czytanie != null ) czytanie.close();

}

System. out.println( loremIpsum );

}

}

Podstawy programowania

Materiały do użytku wewnętrznego

9.9

Strumień znaków - kopiowanie

import java.io.FileReader;

import java.io.FileWriter;

import java.io.IOException;

public class CharStreamKopiowanie

{

public static void main( String[] args ) throws IOException

{

FileReader czytanie = null;

FileWriter pisanie = null;

try {

czytanie = new FileReader( "znaki.txt" );

pisanie = new FileWriter( "znaki-kopia.txt");

int znak;

while ( ( znak = czytanie.read()) != -1 )

pisanie.write( Character. toUpperCase( znak ) );

}

finally {

if (czytanie != null) czytanie.close();

if (pisanie != null) pisanie.close();

}

}

}

Podstawy programowania

Materiały do użytku wewnętrznego

9.10

Strumienie buforowane (1/2)

Czytanie i pisanie pojedynczych bajtów i znaków nie jest efektywne –

zazwyczaj przetwarzaniu podlegają znacznie większe „porcje” danych.

W celu poprawy efektywności operacji WE/WY realizowanych za pomocą

strumieni wprowadzono mechanizm buforowania wspierany przez

odpowiednie klasy buforujące czytanie i pisanie danych.

Buforowane strumienie wejściowe czytają dane z bufora znajdującego się

w pamięci operacyjnej – za wypełnienie bufora (odczytanie danych z

właściwego

źródła

danych)

odpowiedzialne

jest

API

systemu

operacyjnego.

Buforowane strumienie wyjściowe piszą do bufora znajdującego się w

pamięci operacyjnej – gdy bufor zostanie wypełniony, API systemu

operacyjnego przekazuje jego zawartość do właściwego źródła danych

(np. zapisuje go w pliku na dysku).

Podstawy programowania

Materiały do użytku wewnętrznego

9.11

Strumienie buforowane (2/2)

Podstawowymi klasami używanymi do manipulowania buforowanymi

strumieniami

bajtów

są

klasy

BufferedInputStream

oraz

BufferedOutputStream.

Podstawowymi klasami używanymi do manipulowania buforowanymi

strumieniami

znaków

są

klasy

BufferedFileReader

oraz

BufferedFileWriter.

Podstawy programowania

Materiały do użytku wewnętrznego

9.12

Buforowany strumień bajtów - pisanie

import java.io.FileOutputStream;

import java.io.BufferedOutputStream;

import java.io.IOException;

public class ByteStreamBufPisanie

{

public static void main( String[] args ) throws IOException

{

int [] punkty = { 70, 43, 74, 2, 29, 10, 82, 92, 2, 17 };

BufferedOutputStream pisanie = null;

try {

pisanie =

new BufferedOutputStream( new FileOutputStream( "liczby.bin" ), 512 ); for( int k = 0; k < punkty.length; k++ )

pisanie.write( punkty[ k ] );

}

finally {

if ( pisanie != null ) pisanie.close();

}

}

}

Podstawy programowania

Materiały do użytku wewnętrznego

9.13

Buforowany strumień bajtów - czytanie

import java.io.FileInputStream;

import java.io.BufferedInputStream;

import java.io.IOException;

public class ByteStreamBufCzytanie

{

public static void main( String[] args ) throws IOException

{

BufferedInputStream czytanie = null;

int liczba;

try {

czytanie =

new BufferedInputStream( new FileInputStream( "liczby.bin" ), 512 ); while ( ( liczba = czytanie.read() ) != -1 )

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

}

Finally {

if ( czytanie != null ) czytanie.close();

}

}

}

Podstawy programowania

Materiały do użytku wewnętrznego

9.14

Buforowany strumień bajtów - kopiowanie

import java.io.*;

public class ByteStreamBufKopiowanie

{

public static void main( String[] args ) throws IOException

{

BufferedInputStream czytanie = null;

BufferedOutputStream pisanie = null;

try {

czytanie = new BufferedInputStream(

new FileInputStream( "liczby.bin" ), 512 );

pisanie = new BufferedOutputStream(

new FileOutputStream( "liczby-kopia.bin" ), 512 );

int liczba;

while ( ( liczba = czytanie.read()) != -1 ) pisanie.write( liczba );

}

finally {

if ( czytanie != null) czytanie.close();

if ( pisanie != null) pisanie.close();

}

}

}

Podstawy programowania

Materiały do użytku wewnętrznego

9.15

Buforowany strumień znaków - pisanie

import java.io.FileWriter;

import java.io.BufferedWriter;

import java.io.IOException;

public class CharStreamBufPisanie

{

public static void main( String[] args ) throws IOException

{

String loremIpsum =

"Lorem ipsum dolor sit amet, consectetuer adipiscing elit.\n" +

"Nullam feugiat, turpis at pulvinar vulputate, erat libero\n" +

"tristique tellus, nec bibendum odio risus sit amet ante.";

BufferedWriter pisanie = null;

try {

pisanie = new BufferedWriter( new FileWriter( "znaki.txt" ), 512 ); pisanie.write( loremIpsum );

}

finally {

if ( pisanie != null ) pisanie.close();

}

}

}

Podstawy programowania

Materiały do użytku wewnętrznego

9.16

Buforowany strumień znaków - czytanie

import java.io.FileReader;

import java.io.BufferedReader;

import java.io.IOException;

public class CharStreamBufCzytanie

{

public static void main(String[] args) throws IOException

{

String loremIpsum = "";

BufferedReader czytanie = null;

try

{

czytanie = new BufferedReader( new FileReader( "znaki.txt" ), 512 ); while ( ( loremIpsum = czytanie.readLine()) != null )

System. out.println( loremIpsum );

}

finally

{

if ( czytanie != null ) czytanie.close();

}

}

}

Podstawy programowania

Materiały do użytku wewnętrznego

9.17

Buforowany strumień znaków - kopiowanie

import java.io.*;

public class CharStreamBufKopiowanie

{

public static void main( String[] args ) throws IOException

{

BufferedReader czytanie = null;

BufferedWriter pisanie = null;

try {

czytanie = new BufferedReader( new FileReader( "znaki.txt" ), 512 ); pisanie = new BufferedWriter( new FileWriter( "znaki-kopia.txt"), 512 ); String wiersz;

while ( ( wiersz = czytanie.readLine()) != null )

pisanie.write( wiersz.toUpperCase() + "\n" );

}

finally {

if (czytanie != null) czytanie.close();

if (pisanie != null) pisanie.close();

}

}

}

Podstawy programowania

Materiały do użytku wewnętrznego

9.18

Strumienie typów prostych

Strumienie typów prostych umożliwiaja czytanie/pisanie wartości typów

prostych (boolean, char, byte, short, int, long, float, double) oraz klasy String w formacie zgodnym z wewnętrzną reprezentacją języka Java.

Podstawowymi klasami używanymi do manipulowania strumieniami typów

prostych są klasy DataInputStream oraz DataOutputStream.

Podstawy programowania

Materiały do użytku wewnętrznego

9.19

Strumienie typów prostych - pisanie

import java.io.*;

public class DataStreamPisanie

{

public static void main( String[] args ) throws IOException

{

int [] sztuki = { 70, 43, 74, 2, 29 };

double [] cena = { 7.0, 4.3, 7.4, 0.2, 2.9 };

String [] kolor = { "czerwony", "żółty", "zielony", "niebieski", "szary" }; DataOutputStream pisanie = null;

try {

pisanie = new DataOutputStream( new BufferedOutputStream(

new FileOutputStream( "zamowienie.bin" ) ) );

for( int k = 0; k < sztuki.length; k++ )

{

pisanie.writeInt( sztuki[ k ] );

pisanie.writeDouble( cena[ k ] );

pisanie.writeUTF( kolor[ k ] );

}

}

finally {

if ( pisanie != null ) pisanie.close();

}

}

}

Podstawy programowania

Materiały do użytku wewnętrznego

9.20

Strumienie typów prostych - czytanie

import java.io.*;

public class DataStreamCzytanie

{

public static void main( String[] args ) throws IOException

{

int sztuka;

double cena;

String kolor;

DataInputStream czytanie = null;

try

{

czytanie = new DataInputStream(

new BufferedInputStream(

new FileInputStream( "zamowienie.bin" ) ) );

try {

while ( true ) {

sztuka = czytanie.readInt();

cena = czytanie.readDouble();

kolor = czytanie.readUTF();

System. out.format("%4d %6.2f %8.2f %s\n", sztuka, cena, sztuka * cena, kolor );

}

} catch ( EOFException e ) {}

}

finally {

if ( czytanie != null ) czytanie.close();

}

}

}

Podstawy programowania

Materiały do użytku wewnętrznego

9.21

Strumienie obiektów

Strumienie obiektów umożliwiaja czytanie/pisanie wartości typów

obiektowych w formacie zgodnym z wewnętrzną reprezentacją języka

Java.

Strumienie obiektów współpracują z obiektami klas implementującymi

interfejs Serializable.

Podstawowymi klasami używanymi do manipulowania strumieniami typów

prostych są klasy ObjectInputStream oraz ObjectOutputStream.

Podstawy programowania

Materiały do użytku wewnętrznego

9.22

Strumienie obiektów – klasa testowa

import java.io.Serializable;

public class Punkt implements Serializable

{

static final long serialVersionUID = 100L;

double x;

double y;

String kolor;

public Punkt( double aX, double aY, String aKolor )

{

x = aX;

y = aY;

kolor = aKolor;

}

}

Podstawy programowania

Materiały do użytku wewnętrznego

9.23

Strumienie obiektów - pisanie

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.ObjectOutputStream;

public class ObjectStreamPisanie

{

public static void main(String[] args) throws IOException

{

ObjectOutputStream pisanie = null;

Punkt p1 = new Punkt( 2, 4, "czerwony" );

Punkt p2 = new Punkt( 4, 8, "zielony" );

try {

pisanie = new ObjectOutputStream(

new FileOutputStream( "punkty.bin" ) );

pisanie.writeObject( p1 );

pisanie.writeObject( p2 );

}

finally {

if ( pisanie != null ) pisanie.close();

}

}

}

Podstawy programowania

Materiały do użytku wewnętrznego

9.24

Strumienie obiektów - czytanie

import java.io.FileInputStream;

import java.io.ObjectInputStream;

import java.io.EOFException;

import java.io.IOException;

public class ObjectStreamCzytanie

{

public static void main(String[] args) throws IOException, ClassNotFoundException

{

ObjectInputStream czytanie = null;

Punkt p;

try {

czytanie = new ObjectInputStream( new FileInputStream( "punkty.bin" ) ); try {

while ( true ) {

p = ( Punkt ) czytanie.readObject();

System. out.printf( "%6.2f %6.2f %s\n", p.x, p.y, p.kolor );

}

}

catch ( EOFException e ) {}

}

finally {

if ( czytanie != null ) czytanie.close();

}

}

}

Podstawy programowania

Materiały do użytku wewnętrznego

9.25

Pliki o dostępie swobodnym

Pliki o dostępie swobodnym umożliwiają niesekwencyjny dostęp do

danych znajdujących się w pliku, umożliwiając jednoczesne wykonywania

operacji pisania jak i czytania danych.

Typowy sposób przetwarzania pliku składa się z poniższych kroków:

• otwarcie pliku (do czytania, pisania lub czytania/pisania),

• ustawienie pozycji czytania/pisania,

• wykonanie operacji czytania/pisania,

• zamknięcie pliku.

Podstawy programowania

Materiały do użytku wewnętrznego

9.26

Pliki o dostępie swobodnym – przetwarzanie (1/2)

import java.util.Arrays;

import java.io.RandomAccessFile;

import java.io.IOException;

public class RandomAccessPrzetwarzanie

{

public static void main( String[] args ) throws IOException

{

final int ROZ_SZTUKI = 4;

final int ROZ_CENA = 8;

final int ROZ_KOLOR = 50;

final int ROZMIAR = ROZ_SZTUKI + ROZ_CENA + ROZ_KOLOR;

int [] sztuki = { 70, 43, 74, 2, 29 };

double [] cena = { 7.0, 4.3, 7.4, 0.2, 2.9 };

String [] kolor = { "czerwony", "żółty", "zielony", "niebieski", "szary" }; byte [] bufor = new byte[ ROZ_KOLOR ];

RandomAccessFile plik = null;

Podstawy programowania

Materiały do użytku wewnętrznego

9.27

Pliki o dostępie swobodnym – przetwarzanie (1/2)

try

{

plik = new RandomAccessFile( "lista.bin", "rw" );

//pisanie do pliku – nowe dane

for( int k = 0; k < sztuki.length; k++ )

{

plik.writeInt( sztuki[ k ] );

plik.writeDouble( cena[ k ] );

plik.write( Arrays. copyOf( kolor[ k ].getBytes(), ROZ_KOLOR ) );

}

//pisanie do pliku – zmiana zawartości

plik.seek( ROZMIAR * 2 );

plik.writeInt( 83 );

//czytanie z pliku

plik.seek( ROZMIAR * 2 );

int s = plik.readInt();

double c = plik.readDouble();

plik.read( bufor );

System. out.format("%d %f %s\n", s, c, new String( bufor ).trim() );

}

finally {

if ( plik != null ) plik.close();

}

}

}

Podstawy programowania

Materiały do użytku wewnętrznego

9.28