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