Obsługa systemu wejścia-wyjścia Język Java Obsługa systemu wejścia-wyjścia
System wejścia-wyjścia System We/Wy (I/O) - odczyt i zapis danych potrzebnych programom Wejście lub wyjście - np. plik konsola strona internetowa Klasy obsługujące We/Wy - w pakiecie java.io
Pakiet java.io Działania na plikach i katalogach - klasa File Odczyt i zapis danych przy pomocy strumieni (ang. streams) – pojęcie abstrakcyjne reprezentuje źródło lub ujście danych, ukrywa implementację urządzenia I/O
Klasa File Obiekty klasy - pliki lub katalogi, np. File mojPlik = new File("c:/programy/Demo.java"); File mojKatalog = new File("."); Metody klasy - np. exists() - zwraca true, jeśli obiekt istnieje isFile(), isDirectory() canWrite(), canRead() getName(), getPath() length(), lastModified(), renameTo()
Klasa File Metoda list(), list(FilenameFilter) działa tylko dla obiektów będących katalogami zwraca zbiór plików w katalogu – tablicę obiektów String FilenameFilter – interfejs, metoda: boolean accept(dir, fname) Dodatkowe możliwości aplikacji, np. założenie katalogu - metoda mkdirs() usunięcie katalogu lub pliku - metoda delete()
Strumienie Obsługa We/Wy - przy pomocy strumieni Jednakowe algorytmy sekwencyjnego odczytu/zapisu dla wszystkich rodzajów danych Odczyt Zapis otwórz strumień otwórz strumień dopóki są dane dopóki są dane czytaj dane zapisuj dane zamknij strumień zamknij strumień
Rodzaje strumieni Znakowe (sekwencje znaków) od JDK 1.1 potomne po Reader i Writer wczytują/zapisują sekwencje znaków w określonym systemie kodowania automatyczne przekształcanie znaków z/na kod Unicode Bajtowe (sekwencje bajtów) potomne po InputStream i OutputStream głównie do odczytu/zapisu danych binarnych Klasy pomostowe: InputStremReader, OutputStreamWriter
Obsługa strumienia wejściowego Utworzenie obiektu strumienia skojarzonego ze źródłem danych - automatyczne otwarcie strumienia Odczytanie informacji ze strumienia - metoda read() Zamknięcie połączenia ze strumieniem - metoda close()
Obsługa strumienia wyjściowego Utworzenie obiektu strumienia skojarzonego z ujściem danych - automatyczne otwarcie strumienia Zapisanie informacji do strumienia - metoda write() Zamknięcie połączenia ze strumieniem - metoda close()
Klasa InputStream Klasa bazowa dla klas dostarczających na wejście sygnały z różnych źródeł Rodzaje źródeł tablica bajtów obiekt klasy String plik potok (ang. pipe) sekwencja innych strumieni inne (np. połączenia internetowe)
Klasy pochodne po InputStream ByteArrayInputStream - odczyt danych z pamięci (argument – tablica bajtów - bufor) StringBufferInputStream - odczyt danych z pamięci (argument - obiekt klasy String) FileInputStream - odczyt danych z pliku PipedInputStream - odczyt danych z potoku podłączonego do PipedOutputStream innego wątku SequenceInputStream - konkatencja strumieni, dwóch lub obiekt Enumeration FilterInputStream - filtrowanie strumieni – klasa bazowa dekoratorów umożliwiających bardziej przystępną obsługę strumieni niskiego poziomu
Klasa OutputStream Decyduje o rodzaju wyjścia tablica bajtów plik potok Klasy pochodne po OutputStream ByteArrayOutputStream FileOutputStream PipedOutputStream FilterOutputStream
Klasa FileInputStream Argument konstruktora łańcuch znaków z nazwą pliku obiekt klasy File obiekt klasy FileDescriptor Metoda read() zwraca liczbę całkowitą odpowiadającą następnemu bajtowi w strumieniu tablicę bajtów liczbę -1 przy osiągnięciu końca pliku
Klasa FileOutputStream Argument konstruktora - jak w klasie FileInputStream Druga postać konstruktora - z dodatkowym argumentem typu boolean false - zastąpienie zawartości pliku danymi true - dopisanie danych na końcu pliku Zapis danych - metoda write() z argumentem typu int
Aplikacja KopiaPliku import java.io.*; public class KopiaPliku { public static void main (String args[]) { try { FileInputStream p1 = new FileInputStream("dane.txt"); FileOutputStream p2 = new FileOutputStream("wynik.txt"); int dane; while ((dane = p1.read()) != -1) { p2.write(dane); } p1.close(); p2.close(); } catch (IOException e) { System.out.println(e.toString()); }
Klasa FilterInputStream Modyfikacja strumienia wejściowego poprzez dekorator; użycie jest przeźroczyste, ten sam interfejs, czasami rozbudowany; stworzone aby zmniejszyć ilość klas Klasy pochodne po FilterInputStream DataInputStream odczyt danych niezależnie od platformy BufferedInputStream wymuszenie użycia bufora (opcja: rozmiar), zaleca się używać zawsze LineNumberInputStream śledzenie numerów wierszy PushbackInputStream jednobajtowy bufor zwrotny umożliwia zwrot bajtu do strumienia
Klasa DataInputStream Argument konstruktora - obiekt klasy InputStream Metody odczytu danych readBoolean() readByte(), readInt(), readLong(), readShort() readDouble(), readFloat() readChar()
Klasa FilterOutputStream Formatowanie strumienia wyjściowego Klasy pochodne DataOutputStream zapis danych PrintStream formatuje dane na konsolę metody print, println aby nadawały się do odczytania, opcja: czy opróżniać bufor po znaku końca wiersza BufferedOutputStream wymusza użycie bufora Analogiczne metody zapisu w klasie DataOutputStream, np. writeBoolean(),
Przykład użycia klas potomnych po FilterOutputStream int[] x = { 1, 22, 14, 6 }; try { FileOutputStream plik = new FileOutputStream("x.txt"); BufferedOutputStream bufor = new BufferedOutputStream(plik); DataOutputStream dane = new DataOutputStream(bufor); for (int i = 0; i < 4; i ++) dane.writeInt(x[i]); dane.close(); } catch (IOException e) { }
Klasy Reader i Writer Odpowiedniki większości klas potomnych po InputStream i OutputStream, np. FileReader FileInputStream FileWriter FileOutputStream StringReader StringBufferInputStream StringWriter brak odpowiednika CharArrayReader ByteArrayInputStream CharArrayWritter ByteArrayOutputStream
Klasa FileReader Konstruktory - jak w klasie FileInputStream Zwrócenie kodu Unicode kolejnego znaku int read() Zapisanie wczytanych znaków do tablicy int read(char[] tablica, int początek, int ilość) Odczytanie całej linii tekstu - użycie metody readLine() klasy BufferReader String readLine()
Aplikacja CzytanieZnakow import java.io.*; public class CzytanieZnakow { public static void main (String args[]) { try { FileReader plik = new FileReader("dane.txt"); int bajt; while ( (bajt = plik.read()) != -1) System.out.print( (char)bajt); System.out.println(" "); plik.close(); } catch (IOException e) { } }
Przykład czytania wierszy try { FileReader plik = new FileReader("lista.txt"); BufferedReader bufor = new BufferedReader(plik); boolean koniecPliku = false; while (!koniecPliku) { String wiersz = bufor.readLine(); if (wiersz == null) koniecPliku = true; else System.out.println(wiersz); } bufor.close(); } catch (IOException e) { }
Klasa FileWriter Konstruktory - jak w klasie FileOutputStream Zapisanie znaku write(int znak) Zapisanie znaków z tablicy write(char[] tablica, int początek, int ilość) Możliwość użycia klasy BufferedWriter - metoda newLine()
Standardowe we/wy Czytanie ze standardowego wejścia System.in (klawiatura) BufferedReader input = new BufferedReader(new InputStreamReader(System.in)); while((str=input.readLine()).length!=0) System.out.println(str); Zapis do standardowego wyjścia PrintWriter output = new PrintWriter(System.out, true); output.println(„Ala ma kota.”);
Klasa RandomAccesFile Dziedziczy po java.lang.Object Konstruktor (plik, opcja=”r”|”rw”) Do plików o rekordach o znanym rozmiarze Umozliwia dostęp swobodny Metody seek() getFilePointer() Length() metody do przeszukiwania
Kompresja danych Klasy: CheckedInput(Output)Stream – produkuje sumę kontrolną dla dowolnego obiektu Input(Output)Stream ZipInput(Output)Stream – kompresja ZIP GZIPInput(Output)Stream -kompresja GZIP BufferedOutputStream = new BufferedOutputStream(new ZipOutputStream(new FileOutputStream(„plik.zip”)))
Serializacja obiektów ObjectInputStream i ObjectOutputStream - specjalne strumienie do odczytu i zapisu obiektów (serializacji) Mechanizm serializacji zamiana obiektu na sekwencję bajtów przesłanie sekwencji bajtów odtworzenie oryginalnego obiektu Wykorzystanie serializacji - np. RMI
Interfejs Serializable Możliwość serializacji obiektu - jeśli klasa implementuje interfejs Serializable Interfejs Serializable - pusty (brak konieczności przesłaniania metod) Obsługa serializacji - w klasach ObjectInputStream i ObjectOutputStream
Zapis obiektu do strumienia Utworzenie obiektu klasy potomnej po OutputStream "Opakowanie" obiektu w obiekt klasy ObjectOutputStream Wywołanie metody writeObject() Możliwe wystąpienie wyjątku NotSerializableException
Aplikacja PiszObiekt import java.io.*; import java.util.*; public class PiszObiekt implements Serializable { public static void main(String[] args) { Calendar cal = Calendar.getInstance(); Date data = cal.getTime(); try { FileOutputStream p1 = new FileOutputStream("czas"); ObjectOutputStream s = new ObjectOutputStream(p1); s.writeObject("Dzisiaj jest: "); s.writeObject(data); s.close(); } catch (IOException e) { } } }
Odczyt obiektu ze strumienia Utworzenie obiektu klasy potomnej po InputStream "Opakowanie" obiektu w obiekt klasy ObjectInputStream Wywołanie metody readObject()
Aplikacja CzytajObiekt import java.io.*; import java.util.*; public class CzytajObiekt implements Serializable { public static void main(String[] args) { try { FileInputStream p2 = new FileInputStream("czas"); ObjectInputStream s = new ObjectInputStream(p2); String dzisiaj = (String)s.readObject(); Date data = (Date)s.readObject(); s.close(); System.out.println(dzisiaj + data); } catch (IOException e) { } catch (ClassNotFoundException e) { } } }
Eksternalizacja Kontrola serializacji - implementacja interfejsu Externalizable zamiast Serializable Metody interfejsu Externalizable - writeExternal() i readExternal() Przesłonięcie metod interfejsu w klasie
Eksternalizacja public void readExternal(java.io.ObjectInput s) throws ClassNotFoundException, IOException{ nazwisko = s.readUTF(); wiek = s.readInt(); } public void writeExternal(java.io.ObjectOutput s) throws IOException{ s.writeUTF(nazwisko); s.writeInt(wiek);