Darmowy fragment publikacji:
Tytuł oryginału: Core Java, Volume II-Advanced Features (10th Edition)
Tłumaczenie: Piotr Rajca
ISBN: 978-83-283-3479-3
Authorized translation from the English language edition, entitled CORE JAVA, VOLUME II –
ADVANCED FEATURES, 10th Edition; ISBN 0134177290; by Cay S. Horstmann; published by
Pearson Education, Inc, publishing as Prentice Hall.
Copyright © Copyright © 2017 Oracle and/or its affiliates.
Portions © 2017 Cay S. Horstmann
All rights reserved. No part of this book may be reproduced or transmitted in any form or by any
means, electronic or mechanical, including photocopying, recording or by any information storage
retrieval system, without permission from Pearson Education Inc.
Polish language edition published by HELION S.A. Copyright © 2017.
Wszelkie prawa zastrzeżone. Nieautoryzowane rozpowszechnianie całości lub fragmentu niniejszej
publikacji w jakiejkolwiek postaci jest zabronione. Wykonywanie kopii metodą kserograficzną,
fotograficzną, a także kopiowanie książki na nośniku filmowym, magnetycznym lub innym powoduje
naruszenie praw autorskich niniejszej publikacji.
Wszystkie znaki występujące w tekście są zastrzeżonymi znakami firmowymi bądź towarowymi ich
właścicieli.
Autor oraz Wydawnictwo HELION dołożyli wszelkich starań, by zawarte w tej książce informacje
były kompletne i rzetelne. Nie biorą jednak żadnej odpowiedzialności ani za ich wykorzystanie, ani za
związane z tym ewentualne naruszenie praw patentowych lub autorskich. Autor oraz Wydawnictwo
HELION nie ponoszą również żadnej odpowiedzialności za ewentualne szkody wynikłe
z wykorzystania informacji zawartych w książce.
Wydawnictwo HELION
ul. Kościuszki 1c, 44-100 GLIWICE
tel. 32 231 22 19, 32 230 98 63
e-mail: helion@helion.pl
WWW: http://helion.pl (księgarnia internetowa, katalog książek)
Drogi Czytelniku!
Jeżeli chcesz ocenić tę książkę, zajrzyj pod adres
http://helion.pl/user/opinie/javtzx
Możesz tam wpisać swoje uwagi, spostrzeżenia, recenzję.
Pliki z przykładami omawianymi w książce można znaleźć pod adresem:
ftp://ftp.helion.pl/przyklady/javtzx.zip
Printed in Poland.
• Kup książkę
• Poleć książkę
• Oceń książkę
• Księgarnia internetowa
• Lubię to! » Nasza społeczność
Spis treści
Przedmowa ...............................................................................................................................................11
Podziękowania .........................................................................................................................................15
Rozdział 1. Biblioteka strumieni Java SE 8 ..............................................................................................17
1.1. Od iteracji do operacji na strumieniach ................................................................... 18
1.2. Tworzenie strumieni .............................................................................................. 20
1.3. Metody filter, map oraz flatMap .............................................................................. 24
1.4. Pobieranie podstrumieni i łączenie strumieni ........................................................... 25
1.5. Inne przekształcenia strumieni ............................................................................... 26
1.6. Proste operacje redukcji ........................................................................................ 27
1.7. Typ Optional ......................................................................................................... 29
1.7.1. Sposoby posługiwania się wartościami Optional ...................................... 29
1.7.2. Jak nie należy używać wartości opcjonalnych ........................................... 31
1.7.3. Tworzenie obiektów typu Optional .......................................................... 31
1.7.4. Łączenie funkcji zwracających wartości opcjonalne przy użyciu flatMap ...... 32
1.8. Gromadzenie wyników ............................................................................................ 34
1.9. Gromadzenie wyników w mapach ............................................................................ 39
1.10. Grupowanie i podział ........................................................................................... 43
1.11. Kolektory przetwarzające ...................................................................................... 44
1.12. Operacje redukcji ................................................................................................ 48
1.13. Strumienie danych typów prostych ........................................................................ 50
1.14. Strumienie równoległe ......................................................................................... 55
Rozdział 2. Wejście i wyjście ..................................................................................................................61
2.1. Strumienie wejścia-wyjścia ..................................................................................... 61
2.1.1. Odczyt i zapis bajtów ............................................................................. 62
2.1.2. Zoo pełne strumieni .............................................................................. 64
2.1.3. Łączenie filtrów strumieni wejścia-wyjścia ............................................... 68
2.2. Strumienie tekstowe .............................................................................................. 72
2.2.1. Zapisywanie tekstu ............................................................................... 72
2.2.2. Wczytywanie tekstu ............................................................................... 75
2.2.3. Zapis obiektów w formacie tekstowym .................................................... 75
2.2.4. Zbiory znaków ...................................................................................... 78
Poleć książkęKup książkę4
Java. Techniki zaawansowane
2.3. Odczyt i zapis danych binarnych .............................................................................. 81
2.3.1. Interfejsy DataInput oraz DataOutput ...................................................... 81
2.3.2. Strumienie plików o swobodnym dostępie ............................................... 84
2.3.3. Archiwa ZIP .......................................................................................... 88
2.4. Strumienie obiektów i serializacja ........................................................................... 91
2.4.1. Zapisywanie i wczytywanie obiektów serializowalnych .............................. 91
2.4.2. Format pliku serializacji obiektów ........................................................... 95
2.4.3. Modyfikowanie domyślnego mechanizmu serializacji .............................. 102
2.4.4. Serializacja singletonów i wyliczeń ....................................................... 104
2.4.5. Wersje ............................................................................................... 105
2.4.6. Serializacja w roli klonowania .............................................................. 107
2.5. Zarządzanie plikami ............................................................................................. 109
2.5.1. Ścieżki dostępu .................................................................................. 110
2.5.2. Odczyt i zapis plików ........................................................................... 112
2.5.3. Tworzenie plików i katalogów ............................................................... 114
2.5.4. Kopiowanie, przenoszenie i usuwanie plików ......................................... 115
2.5.5. Informacje o plikach ........................................................................... 117
2.5.6. Przeglądanie zawartości katalogu ......................................................... 118
2.5.7. Stosowanie strumieni katalogów .......................................................... 120
2.5.8. Systemy plików ZIP ............................................................................. 123
2.6. Mapowanie plików w pamięci ............................................................................... 124
2.6.1. Wydajność plików mapowanych w pamięci ............................................ 124
2.6.2. Struktura bufora danych ...................................................................... 131
2.6.3. Blokowanie plików .............................................................................. 133
2.7. Wyrażenia regularne ............................................................................................ 135
Rozdział 3. Język XML ...........................................................................................................................149
3.1. Wprowadzenie do języka XML ............................................................................... 150
3.1.1. Struktura dokumentu XML ................................................................... 152
3.2. Parsowanie dokumentów XML .............................................................................. 155
3.3. Kontrola poprawności dokumentów XML ............................................................... 166
3.3.1. Definicje typów dokumentów ............................................................... 167
3.3.2. XML Schema ...................................................................................... 174
3.3.3. Praktyczny przykład ............................................................................. 176
3.4. Wyszukiwanie informacji i XPath ........................................................................... 189
3.5. Przestrzenie nazw ................................................................................................ 195
3.6. Parsery strumieniowe .......................................................................................... 198
3.6.1. Wykorzystanie parsera SAX ................................................................. 198
3.6.2. Wykorzystanie parsera StAX ................................................................ 203
3.7. Tworzenie dokumentów XML ................................................................................ 207
3.7.1. Dokumenty bez przestrzeni nazw .......................................................... 207
3.7.2. Dokumenty z przestrzenią nazw ........................................................... 208
3.7.3. Zapisywanie dokumentu ...................................................................... 209
3.7.4. Przykład: tworzenie pliku SVG .............................................................. 209
3.7.5. Tworzenie dokumentu XML za pomocą parsera StAX ............................. 213
3.8. Przekształcenia XSL ............................................................................................ 220
Rozdział 4. Programowanie aplikacji sieciowych ...............................................................................231
4.1. Połączenia z serwerem ........................................................................................ 231
4.1.1. Stosowanie programu telnet ................................................................ 231
4.1.2. Nawiązywanie połączenia z serwerem z wykorzystaniem Javy .................. 234
4.1.3. Limity czasu gniazd ............................................................................. 235
4.1.4. Adresy internetowe ............................................................................. 237
Poleć książkęKup książkę
Spis treści
5
4.2. Implementacja serwerów ..................................................................................... 238
4.2.1. Gniazda serwera ................................................................................. 239
4.2.2. Obsługa wielu klientów ........................................................................ 241
4.2.3. Połączenia częściowo zamknięte .......................................................... 244
4.3. Przerywanie działania gniazd sieciowych ................................................................ 246
4.4. Połączenia wykorzystujące URL ............................................................................. 252
4.4.1. URL i URI ........................................................................................... 252
4.4.2. Zastosowanie klasy URLConnection do pobierania informacji ................. 254
4.4.3. Wysyłanie danych do formularzy ........................................................... 262
4.5. Wysyłanie poczty elektronicznej ............................................................................ 270
Rozdział 5. Programowanie baz danych: JDBC ...................................................................................275
5.1. Architektura JDBC ............................................................................................... 276
5.1.1. Typy sterowników JDBC ....................................................................... 276
5.1.2. Typowe zastosowania JDBC ................................................................. 278
5.2. Język SQL ........................................................................................................... 278
5.3. Instalacja JDBC ................................................................................................... 284
5.3.1. Adresy URL baz danych ....................................................................... 284
5.3.2. Pliki JAR zawierające sterownik ............................................................ 285
5.3.3. Uruchamianie bazy danych .................................................................. 285
5.3.4. Rejestracja klasy sterownika ............................................................... 286
5.3.5. Nawiązywanie połączenia z bazą danych ............................................... 287
5.4. Stosowanie poleceń SQL ..................................................................................... 289
5.4.1. Wykonywanie poleceń SQL .................................................................. 290
5.4.2. Zarządzanie połączeniami, poleceniami i zbiorami wyników .................... 293
5.4.3. Analiza wyjątków SQL .......................................................................... 294
5.4.4. Wypełnianie bazy danych ..................................................................... 296
5.5. Wykonywanie zapytań .......................................................................................... 300
5.5.1. Polecenia przygotowane ...................................................................... 300
5.5.2. Odczyt i zapis dużych obiektów ............................................................ 306
5.5.3. Sekwencje sterujące ........................................................................... 308
5.5.4. Zapytania o wielu zbiorach wyników ...................................................... 309
5.5.5. Pobieranie wartości kluczy wygenerowanych automatycznie .................... 310
5.6. Przewijalne i aktualizowalne zbiory wyników zapytań ............................................... 311
5.6.1. Przewijalne zbiory wyników ................................................................... 311
5.6.2. Aktualizowalne zbiory rekordów ............................................................ 313
5.7. Zbiory rekordów ................................................................................................... 318
5.7.1. Tworzenie zbiorów rekordów ................................................................ 318
5.7.2. Buforowane zbiory rekordów ................................................................ 319
5.8. Metadane ........................................................................................................... 322
5.9. Transakcje .......................................................................................................... 331
5.9.1. Programowanie transakcji w JDBC ........................................................ 332
5.9.2. Punkty kontrolne ................................................................................. 332
5.9.3. Aktualizacje wsadowe ......................................................................... 333
5.10. Zaawansowane typy języka SQL .......................................................................... 335
5.11. Zaawansowane zarządzanie połączeniami ........................................................... 336
Rozdział 6. API dat i czasu ....................................................................................................................339
6.1. Oś czasu ............................................................................................................ 340
6.2. Daty lokalne ....................................................................................................... 343
6.3. Modyfikatory dat ................................................................................................. 346
6.4. Czas lokalny ....................................................................................................... 347
Poleć książkęKup książkę6
Java. Techniki zaawansowane
6.5. Czas strefowy ..................................................................................................... 348
6.6. Formatowanie i parsowanie .................................................................................. 352
6.7. Współdziałanie ze starym kodem .......................................................................... 356
Rozdział 7. Internacjonalizacja ............................................................................................................359
7.1. Lokalizatory ........................................................................................................ 360
7.2. Formaty liczb ....................................................................................................... 365
7.3. Waluty ................................................................................................................ 370
7.4. Data i czas ......................................................................................................... 372
7.5. Porządek alfabetyczny i normalizacja ..................................................................... 378
7.6. Formatowanie komunikatów ................................................................................. 385
7.6.1. Formatowanie liczb i dat ...................................................................... 385
7.6.2. Formatowanie z wariantami ................................................................. 387
7.7. Wczytywanie i wyświetlanie tekstów ...................................................................... 389
7.7.1. Pliki tekstowe ..................................................................................... 389
7.7.2. Znaki końca wiersza ........................................................................... 389
7.7.3. Konsola ............................................................................................. 390
7.7.4. Pliki dzienników .................................................................................. 391
7.7.5. BOM — znacznik kolejności bajtów UTF-8 ............................................. 391
7.7.6. Kodowanie plików źródłowych .............................................................. 392
7.8. Komplety zasobów .............................................................................................. 392
7.8.1. Wyszukiwanie kompletów zasobów ....................................................... 393
7.8.2. Pliki właściwości ................................................................................. 394
7.8.3. Klasy kompletów zasobów ................................................................... 395
7.9. Kompletny przykład ............................................................................................. 397
Rozdział 8. Skrypty, kompilacja i adnotacje .........................................................................................413
8.1. Skrypty na platformie Java ................................................................................... 413
8.1.1. Wybór silnika skryptów ........................................................................ 414
8.1.2. Wykonywanie skryptów i wiązania zmiennych ........................................ 415
8.1.3. Przekierowanie wejścia i wyjścia .......................................................... 417
8.1.4. Wywoływanie funkcji i metod skryptów .................................................. 418
8.1.5. Kompilacja skryptu ............................................................................. 420
8.1.6. Przykład: skrypty i graficzny interfejs użytkownika .................................. 420
8.2. Interfejs kompilatora ........................................................................................... 425
8.2.1. Kompilacja w najprostszy sposób ......................................................... 426
8.2.2. Stosowanie zadań kompilacji ............................................................... 426
8.2.3. Przykład: dynamiczne tworzenie kodu w języku Java ............................... 432
8.3. Stosowanie adnotacji .......................................................................................... 436
8.3.1. Wprowadzenie do stosowania adnotacji ................................................ 437
8.3.2. Przykład: adnotacje obsługi zdarzeń ..................................................... 438
8.4. Składnia adnotacji ............................................................................................... 443
8.4.1. Interfejsy adnotacji ............................................................................. 443
8.4.2. Adnotacje .......................................................................................... 445
8.4.3. Adnotacje deklaracji ............................................................................ 446
8.4.4. Adnotacje zastosowań typów ............................................................... 447
8.4.5. Adnotacje i this .................................................................................. 449
8.5. Adnotacje standardowe ....................................................................................... 450
8.5.1. Adnotacje kompilacji ........................................................................... 451
8.5.2. Adnotacje zarządzania zasobami .......................................................... 451
8.5.3. Metaadnotacje ................................................................................... 452
Poleć książkęKup książkę
Spis treści
7
8.6. Przetwarzanie adnotacji w kodzie źródłowym .......................................................... 455
8.6.1. Procesory adnotacji ............................................................................ 455
8.6.2. Interfejs programowy modelu języka ..................................................... 455
8.6.3. Stosowanie adnotacji do generacji kodu źródłowego .............................. 456
8.7. Inżynieria kodu bajtowego .................................................................................... 459
8.7.1. Modyfikowanie plików klasowych ......................................................... 459
8.7.2. Modyfikacja kodu bajtowego podczas ładowania ................................... 464
Rozdział 9. Bezpieczeństwo .................................................................................................................467
9.1. Ładowanie klas ................................................................................................... 468
9.1.1. Proces wczytywania plików klas ........................................................... 468
9.1.2. Hierarchia klas ładowania ................................................................... 469
9.1.3. Zastosowanie procedur ładujących w roli przestrzeni nazw ..................... 471
9.1.4. Implementacja własnej procedury ładującej ........................................... 473
9.1.5. Weryfikacja kodu maszyny wirtualnej .................................................... 478
9.2. Menedżery bezpieczeństwa i pozwolenia ............................................................... 483
9.2.1. Sprawdzanie uprawnień ....................................................................... 483
9.2.2. Bezpieczeństwo na platformie Java ...................................................... 484
9.2.3. Pliki polityki bezpieczeństwa ................................................................ 487
9.2.4. Tworzenie własnych klas pozwoleń ....................................................... 495
9.2.5. Implementacja klasy pozwoleń ............................................................. 496
9.3. Uwierzytelnianie użytkowników .............................................................................. 502
9.3.1. Framework JAAS ................................................................................. 502
9.3.2. Moduły JAAS ...................................................................................... 507
9.4. Podpis cyfrowy .................................................................................................... 516
9.4.1. Skróty wiadomości .............................................................................. 517
9.4.2. Podpisywanie wiadomości ................................................................... 520
9.4.3. Weryfikacja podpisu ............................................................................ 522
9.4.4. Problem uwierzytelniania ..................................................................... 524
9.4.5. Podpisywanie certyfikatów ................................................................... 526
9.4.6. Żądania certyfikatu ............................................................................. 527
9.4.7. Podpisywanie kodu ............................................................................. 528
9.5. Szyfrowanie ........................................................................................................ 534
9.5.1. Szyfrowanie symetryczne ..................................................................... 534
9.5.2. Generowanie klucza ............................................................................ 536
9.5.3. Strumienie szyfrujące .......................................................................... 541
9.5.4. Szyfrowanie kluczem publicznym .......................................................... 542
Rozdział 10. Zaawansowane możliwości pakietu Swing .....................................................................547
10.1. Listy ................................................................................................................. 547
10.1.1. Komponent JList .............................................................................. 548
10.1.2. Modele list ....................................................................................... 553
10.1.3. Wstawianie i usuwanie ...................................................................... 558
10.1.4. Odrysowywanie zawartości listy .......................................................... 559
10.2. Tabele .............................................................................................................. 563
10.2.1. Najprostsze tabele ............................................................................ 563
10.2.2. Modele tabel .................................................................................... 568
10.2.3. Wiersze i kolumny ............................................................................. 571
10.2.4. Rysowanie i edycja komórek .............................................................. 586
Poleć książkęKup książkę8
Java. Techniki zaawansowane
10.3. Drzewa ............................................................................................................. 598
10.3.1. Najprostsze drzewa ........................................................................... 599
10.3.2. Modyfikacje drzew i ścieżek drzew ..................................................... 606
10.3.3. Przeglądanie węzłów ......................................................................... 613
10.3.4. Rysowanie węzłów ............................................................................ 615
10.3.5. Nasłuchiwanie zdarzeń w drzewach .................................................... 618
10.3.6. Własne modele drzew ....................................................................... 625
10.4. Komponenty tekstowe ....................................................................................... 633
10.4.1. Śledzenie zmian zawartości komponentów tekstowych ......................... 634
10.4.2. Sformatowane pola wejściowe ........................................................... 637
10.4.3. Komponent JSpinner ......................................................................... 653
10.4.4. Prezentacja HTML za pomocą JEditorPane .......................................... 661
10.5. Wskaźniki postępu ............................................................................................ 667
10.5.1. Paski postępu .................................................................................. 667
10.5.2. Monitory postępu ............................................................................. 670
10.5.3. Monitorowanie postępu strumieni wejścia .......................................... 673
10.6. Organizatory komponentów i dekoratory .............................................................. 678
10.6.1. Panele dzielone ................................................................................ 678
10.6.2. Panele z kartami ............................................................................... 681
10.6.3. Panele pulpitu i ramki wewnętrzne ..................................................... 687
10.6.4. Warstwy ........................................................................................... 703
Rozdział 11. Zaawansowane możliwości biblioteki AWT ......................................................................709
11.1. Potokowe tworzenie grafiki ................................................................................. 710
11.2. Figury ............................................................................................................... 712
11.2.1. Hierarchia klas Shape ....................................................................... 713
11.2.2. Wykorzystanie klas obiektów graficznych ............................................ 714
11.3. Pola ................................................................................................................. 727
11.4. Ślad pędzla ....................................................................................................... 728
11.5. Wypełnienia ...................................................................................................... 735
11.6. Przekształcenia układu współrzędnych ................................................................ 737
11.7. Przycinanie ....................................................................................................... 743
11.8. Przezroczystość i składanie obrazów ................................................................... 745
11.9. Wskazówki operacji graficznych .......................................................................... 753
11.10. Czytanie i zapisywanie plików graficznych .......................................................... 758
11.10.1. Wykorzystanie obiektów zapisu i odczytu plików graficznych ............... 759
11.10.2. Odczyt i zapis plików zawierających sekwencje obrazów ..................... 763
11.11. Operacje na obrazach ...................................................................................... 768
11.11.1. Dostęp do danych obrazu ................................................................ 769
11.11.2. Filtrowanie obrazów ........................................................................ 775
11.12. Drukowanie .................................................................................................... 783
11.12.1. Drukowanie grafiki .......................................................................... 784
11.12.2. Drukowanie wielu stron ................................................................... 792
11.12.3. Podgląd wydruku ............................................................................ 794
11.12.4. Usługi drukowania .......................................................................... 802
11.12.5. Usługi drukowania za pośrednictwem strumieni ................................ 806
11.12.6. Atrybuty drukowania ........................................................................ 807
11.13. Schowek ........................................................................................................ 813
11.13.1. Klasy i interfejsy umożliwiające przekazywanie danych ....................... 814
11.13.2. Przekazywanie tekstu ...................................................................... 815
11.13.3. Interfejs Transferable i formaty danych ............................................. 818
Poleć książkęKup książkę
Spis treści
9
11.13.4. Przekazywanie obrazów za pomocą schowka ..................................... 820
11.13.5. Wykorzystanie schowka systemowego
do przekazywania obiektów Java ................................................................. 824
11.13.6. Zastosowanie lokalnego schowka
do przekazywania referencji obiektów .......................................................... 827
11.14. Mechanizm „przeciągnij i upuść” ...................................................................... 828
11.14.1. Przekazywanie danych pomiędzy komponentami Swing ...................... 829
11.14.2. Źródła przeciąganych danych ........................................................... 833
11.14.3. Cele upuszczanych danych .............................................................. 835
11.15. Integracja z macierzystą platformą .................................................................... 844
11.15.1. Ekran powitalny .............................................................................. 844
11.15.2. Uruchamianie macierzystych aplikacji pulpitu .................................... 849
11.15.3. Zasobnik systemowy ....................................................................... 853
Rozdział 12. Metody macierzyste .........................................................................................................859
12.1. Wywołania funkcji języka C z programów w języku Java ......................................... 860
12.2. Numeryczne parametry metod i wartości zwracane ............................................... 866
12.3. Łańcuchy znaków jako parametry ........................................................................ 868
12.4. Dostęp do składowych obiektu ........................................................................... 873
12.4.1. Dostęp do pól instancji ..................................................................... 874
12.4.2. Dostęp do pól statycznych ................................................................. 877
12.5. Sygnatury ......................................................................................................... 878
12.6. Wywoływanie metod języka Java ......................................................................... 880
12.6.1. Wywoływanie metod obiektów ............................................................ 880
12.6.2. Wywoływanie metod statycznych ........................................................ 883
12.6.3. Konstruktory .................................................................................... 884
12.6.4. Alternatywne sposoby wywoływania metod .......................................... 885
12.7. Tablice ............................................................................................................. 886
12.8. Obsługa błędów ................................................................................................ 890
12.9. Interfejs programowy wywołań języka Java ........................................................... 895
12.10. Kompletny przykład: dostęp do rejestru systemu Windows .................................. 900
12.10.1. Rejestr systemu Windows ............................................................... 900
12.10.2. Interfejs dostępu do rejestru na platformie Java ................................ 902
12.10.3. Implementacja dostępu do rejestru
za pomocą metod macierzystych ................................................................. 902
Skorowidz .............................................................................................................................................917
Poleć książkęKup książkę10
Java. Techniki zaawansowane
Poleć książkęKup książkę2
Wejście i wyjście
W tym rozdziale:
2.1. Strumienie wejścia-wyjścia.
2.2. Strumienie tekstowe.
2.3. Odczyt i zapis danych binarnych.
2.4. Strumienie obiektów i serializacja.
2.5. Zarządzanie plikami.
2.6. Pliki mapowane w pamięci.
2.7. Wyrażenia regularne.
W tym rozdziale omówimy interfejsy programowe związane z obsługą wejścia i wyjścia
programów. Przedstawimy sposoby dostępu do plików i katalogów oraz sposoby zapisywa-
nia do i wczytywania informacji z plików w formacie tekstowym i binarnym. W rozdziale
przedstawiony jest również mechanizm serializacji obiektów, który umożliwia przechowy-
wanie obiektów z taką łatwością, z jaką przechowujesz tekst i dane numeryczne. Następnie
zajmiemy się zagadnieniami związanymi z obsługą plików i katalogów. Rozdział zakończymy
przedstawieniem problematyki wyrażeń regularnych, mimo że nie jest ona bezpośrednio związa-
na z zagadnieniami wejścia-wyjścia. Nie potrafiliśmy jednak znaleźć dla niej lepszego miejsca
w książce. W naszym wyborze nie byliśmy zresztą osamotnieni, ponieważ zespół Javy dołączył
specyfikację interfejsów programowych związanych z przetwarzaniem wyrażeń regularnych
do specyfikacji „nowej wersji” obsługi wejścia i wyjścia.
2.1. Strumienie wejścia-wyjścia
W języku Java obiekt, z którego możemy odczytać sekwencję bajtów, nazywamy strumie-
niem wejścia. Obiekt, do którego możemy zapisać sekwencję bajtów, nazywamy strumieniem
wyjścia. Źródłem bądź celem tych sekwencji bajtów mogą być, i często właśnie są, pliki,
ale także i połączenia sieciowe, a nawet bloki pamięci. Klasy abstrakcyjne InputStream
i OutputStream stanowią bazę hierarchii klas opisujących wejście i wyjście programów Java.
Poleć książkęKup książkę62
Java. Techniki zaawansowane
Te strumienie wejścia i wyjścia nie są powiązane ze strumieniami, które zostały
opisane w poprzednim rozdziale. Dla jasności w przypadku opisywania strumieni
związanych z operacjami wejścia i wyjścia zawsze będziemy używali terminów „strumień
wejścia”, „strumień wyjścia” lub „strumień wejścia-wyjścia”.
Ponieważ binarne strumienie wejścia-wyjścia nie są zbyt wygodne do manipulacji danymi
przechowywanymi w standardzie Unicode (przypomnijmy tutaj, że Unicode opisuje każdy
znak za pomocą dwóch bajtów), stworzono osobną hierarchię klas operujących na znakach
Unicode i dziedziczących po klasach abstrakcyjnych Reader i Writer. Klasy te są przystosowa-
ne do wykonywania operacji odczytu i zapisu, opartych na wartościach char (czyli znaków
UTF-16), nie przydają się natomiast do operacji na wartościach typu byte.
2.1.1. Odczyt i zapis bajtów
Klasa InputStream posiada metodę abstrakcyjną:
abstract int read()
Metoda ta wczytuje jeden bajt i zwraca jego wartość lub –1, jeżeli natrafi na koniec źródła
danych. Projektanci konkretnych klas strumieni wejścia przesłaniają tę metodę, dostarczając
w ten sposób użytecznej funkcjonalności. Dla przykładu, w klasie FileInputStream metoda read
czyta jeden bajt z pliku. System.in to predefiniowany obiekt klasy pochodnej od InputStream,
pozwalający pobierać informacje ze „standardowego wejścia”, czyli konsoli lub przekiero-
wanego pliku.
Klasa InputStream posiada również nieabstrakcyjne metody pozwalające pobrać lub zignoro-
wać tablicę bajtów. Metody te wywołują abstrakcyjną metodę read, tak więc podklasy muszą
przesłaniać tylko tę jedną metodę.
Analogicznie, klasa OutputStream definiuje metodę abstrakcyjną
abstract void write(int b)
która wysyła jeden bajt do aktualnego wyjścia.
Metody read i write potrafią zablokować wątek, dopóki dany bajt nie zostanie wczytany lub
zapisany. Oznacza to, że jeżeli strumień wejścia nie może natychmiastowo wczytać lub zapisać
danego bajta (zazwyczaj z powodu powolnego połączenia sieciowego), Java zawiesza wątek
dokonujący wywołania. Dzięki temu inne wątki mogą wykorzystać czas procesora, w którym
wywołana metoda czeka na udostępnienie strumienia.
Metoda available pozwala sprawdzić liczbę bajtów, które w danym momencie odczytać.
Oznacza to, że poniższy kod prawdopodobnie nigdy nie zostanie zablokowany:
int bytesAvaible = System.in.available();
if (bytesAvaible 0)
{
byte[] dane = new byte[bytesAvaible];
System.in.read(data);
}
Poleć książkęKup książkęRozdział 2. Wejście i wyjście
63
Gdy skończymy odczytywać albo zapisywać dane do strumienia wejścia-wyjścia, zamykamy
go, wywołując metodę close. Metoda ta uwalnia zasoby systemu operacyjnego, do tej pory
udostępnione wątkowi. Jeżeli aplikacja otworzy zbyt wiele strumieni wejścia-wyjścia, nie za-
mykając ich, zasoby systemu mogą zostać naruszone. Co więcej, zamknięcie strumienia wyjścia
powoduje opróżnienie bufora używanego przez ten strumień — wszystkie bajty, przecho-
wywane tymczasowo w buforze, aby mogły zostać zapisane w jednym większym pakiecie,
zostaną natychmiast wysłane. Jeżeli nie zamkniemy strumienia, ostatni pakiet bajtów może
nigdy nie dotrzeć do odbiorcy. Bufor możemy również opróżnić własnoręcznie, przy użyciu
metody flush.
Mimo iż klasy strumieni wejścia-wyjścia udostępniają konkretne metody wykorzystujące
funkcje read i write, programiści Javy rzadko z nich korzystają, ponieważ nieczęsto się zdarza,
żeby programy musiały czytać i zapisywać sekwencje bajtów. Dane, którymi jesteśmy zwy-
kle bardziej zainteresowani, to liczby, łańcuchy znaków i obiekty.
Zamiast operować na bajtach, można skorzystać z jednej z wielu klas strumieni pocho-
dzących od podstawowych klas InputStream i OutputStream.
java.io.InputStream 1.0
abstract int read()
pobiera jeden bajt i zwraca jego wartość. Metoda read zwraca –1, gdy natrafi
na koniec strumienia wejścia.
int read(byte[] b)
wczytuje dane do tablicy i zwraca liczbę wczytanych bajtów, a jeżeli natrafi
na koniec strumienia wejścia, zwraca –1. Metoda read czyta co najwyżej b.length
bajtów.
int read(byte[] b, int off, int len)
wczytuje dane do tablicy bajtów. Zwraca liczbę wczytanych bajtów, a jeżeli natrafi
na koniec strumienia wejścia, zwraca –1.
Parametry:
b
off
tablica, w której zapisywane są dane.
indeks tablicy b, pod którym powinien zostać
umieszczony pierwszy wczytany bajt.
maksymalna liczba wczytywanych bajtów.
len
long skip(long n)
ignoruje n bajtów w strumieniu wejścia. Zwraca faktyczną liczbę zignorowanych
bajtów (która może być mniejsza niż n, jeżeli natrafimy na koniec strumienia
wejścia).
int available()
zwraca liczbę bajtów dostępnych bez konieczności zablokowania wątku (pamiętajmy,
że zablokowanie oznacza, że wykonanie aktualnego wątku zostaje wstrzymane).
void close()
zamyka strumień wejścia.
Poleć książkęKup książkę64
Java. Techniki zaawansowane
void mark(int readlimit)
ustawia znacznik na aktualnej pozycji strumienia wejścia (nie wszystkie strumienie
obsługują tę możliwość). Jeżeli ze strumienia zostało pobranych więcej niż readlimit
bajtów, strumień ma prawo usunąć znacznik.
void reset()
wraca do ostatniego znacznika. Późniejsze wywołania read będą powtórnie czytać
pobrane już bajty. Jeżeli znacznik nie istnieje, strumień wejścia nie zostanie zresetowany.
boolean markSupported()
zwraca true, jeżeli strumień wejścia obsługuje znaczniki.
java.io.OutputStream 1.0
abstract void write(int n)
zapisuje jeden bajt.
void write(byte[] b)
void write(byte[] b, int off, int len)
zapisują wszystkie bajty tablicy b lub pewien ich zakres.
Parametry:
b
off
tablica, z której pobierane są dane.
indeks tablicy b, spod którego powinien zostać
pobrany pierwszy zapisywany bajt.
liczba zapisywanych bajtów.
len
void close()
opróżnia i zamyka strumień wyjścia.
void flush()
opróżnia strumień wyjścia, czyli wysyła do odbiorcy wszystkie dane znajdujące
się w buforze.
2.1.2. Zoo pełne strumieni
W przeciwieństwie do języka C, który w zupełności zadowala się jednym typem FILE*, Java po-
siada istne zoo ponad 60 (!) różnych typów strumieni wejścia i wyjścia (patrz rysunki 2.1 i 2.2).
Podzielmy gatunki należące do zoo strumieni zależnie od ich przeznaczenia. Istnieją osob-
ne hierarchie klas przetwarzających bajty i znaki. Jak już o tym wspomnieliśmy, klasy Inpu-
tStream i OutputStream pozwalają pobierać i wysyłać jedynie pojedyncze bajty oraz tablice
bajtów. Klasy te stanowią bazę hierarchii pokazanej na rysunku 2.1. Do odczytu i zapisu liczb
i łańcuchów znakowych używamy ich podklas. Na przykład, DataInputStream i DataOutput
Stream pozwalają wczytywać i zapisywać wszystkie podstawowe typy Javy w postaci binar-
nej. I w końcu istnieje także wiele pożytecznych klas strumieni, na przykład ZipInputStream
i ZipOutputStream pozwalające odczytywać i zapisywać dane w plikach skompresowanych
w formacie ZIP.
Poleć książkęKup książkęRozdział 2. Wejście i wyjście
65
Rysunek 2.1. Hierarchia strumieni wejścia i wyjścia
Z drugiej strony, o czym już wspominaliśmy, do obsługi tekstu Unicode używamy klas pocho-
dzących od klas abstrakcyjnych Reader i Writer (patrz rysunek 2.2) Podstawowe metody klas
Reader i Writer są podobne do tych należących do InputStream i OutputStream.
abstract int read()
abstract void write(int b)
Metoda read zwraca albo kod znaku UTF-16 (jako liczbę z przedziału od 0 do 65535), albo –1,
jeżeli natrafi na koniec pliku. Metoda write jest wywoływana dla podanego kodu znaku
Unicode (więcej informacji na temat kodów Unicode znajdziesz w rozdziale 3. książki
Java. Podstawy).
Poleć książkęKup książkę66
Java. Techniki zaawansowane
Rysunek 2.2. Hierarchia klas Reader i Writer
Dostępne są również cztery dodatkowe interfejsy: Closeable, Flushable, Readable i Appendable
(patrz rysunek 2.3). Pierwsze dwa z nich są wyjątkowo proste i zawierają odpowiednio metody:
void close() throws IOException
i
void flush()
Klasy InputStream, OutputStream, Reader i Writer implementują interfejs Closeable.
Interfejs java.io.Closeable stanowi rozszerzenie interfejsu java.lang.Auto
Closeable. Dzięki temu dla każdego obiektu implementującego interfejs Close
able możemy użyć wersji instrukcji try zarządzającej zasobami. Ale po co nam dwa in-
terfejsy? Metoda close interfejsu Closeable może wyrzucać jedynie wyjątek IOException,
podczas gdy metoda AutoCloseable.close może wyrzucać wyjątek dowolnej klasy.
Klasy OutputStream i Writer implementują interfejs Flushable.
Interfejs Readable ma tylko jedną metodę
int read(CharBuffer cb)
Klasa CharBuffer ma metody do sekwencyjnego oraz swobodnego odczytu i zapisu. Reprezentuje
ona bufor w pamięci lub mapę pliku w pamięci. (Patrz punkt 2.6.2, „Struktura bufora danych”).
Poleć książkęKup książkęRozdział 2. Wejście i wyjście
67
Rysunek 2.3. Interfejsy Closeable, Flushable, Readable i Appendable
Interfejs Appendable ma dwie metody umożliwiające dopisywanie pojedynczego znaku bądź
sekwencji znaków:
Appendable append(char c)
Appendable append(CharSequence s)
Interfejs CharSequence opisuje podstawowe właściwości sekwencji wartości typu char. Inter-
fejs ten implementują klasy String, CharBuffer, StringBuilder i StringBuffer.
Spośród klas strumieni wejścia-wyjścia jedynie klasa Writer implementuje interfejs Appendable.
java.io.Closeable 5.0
void close()
zamyka obiekt implementujący interfejs Closeable. Może wyrzucić wyjątek
IOException.
java.io.Flushable 5.0
void flush()
opróżnia bufor danych związany z obiektem implementującym interfejs Flushable.
java.lang.Readable 5.0
int read(CharBuffer cb)
próbuje wczytać tyle wartości typu char, ile może pomieścić cb. Zwraca liczbę
wczytanych wartości lub -1, jeśli obiekt Readable nie ma już wartości do pobrania.
Poleć książkęKup książkę68
Java. Techniki zaawansowane
java.lang.Appendable 5.0
Appendable append(char c)
Appendable append(CharSequence cs)
dopisuje podany kod znaku lub wszystkie kody podanej sekwencji do obiektu
Appendable; zwraca this.
java.lang.CharSequence 1.4
char charAt(int index)
zwraca kod o podanym indeksie.
int length()
zwraca liczbę kodów w sekwencji.
CharSequence subSequence(int startIndex, int endIndex)
zwraca sekwencję CharSequence złożoną z kodów od startIndex do endIndex - 1.
String toString()
zwraca łańcuch znaków składający się z kodów danej sekwencji.
2.1.3. Łączenie filtrów strumieni wejścia-wyjścia
Klasy FileInputStream i FileOutputStream obsługują strumienie wejścia i wyjścia przypo-
rządkowane określonemu plikowi na dysku. W konstruktorze tych klas podajemy nazwę pliku
lub pełną ścieżkę dostępu do niego. Na przykład
FileInputStream fin = new FileInputStream( employee.dat );
spróbuje odszukać w aktualnym katalogu plik o nazwie employee.dat.
Ponieważ wszystkie klasy w java.io uznają relatywne ścieżki dostępu za rozpo-
czynające się od aktualnego katalogu roboczego, powinieneś wiedzieć, co to za ka-
talog. Możesz pobrać tę informację poleceniem System.getProperty( user.dir ).
Ponieważ znak \ w łańcuchach na platformie Java jest traktowany jako początek
sekwencji specjalnej, musimy pamiętać, aby w ścieżkach dostępu do plików sys-
temu Windows używać sekwencji \\ (np. C:\\Windows\\win.ini). W systemie Windows
możemy również korzystać ze znaku / (np. C:/Windows/win.ini), ponieważ większość
wywołań systemu obsługi plików Windows interpretuje znaki / jako separatory ścieżki
dostępu. Jednakże nie zalecamy tego rozwiązania — zachowanie funkcji systemu Win-
dows może się zmienić. Jeżeli piszemy aplikację przenośną, powinniśmy używać sepa-
ratora odpowiedniego dla danego systemu operacyjnego. Jego znak jest przechowywany
jako stała java.io.File.separator.
Poleć książkęKup książkęRozdział 2. Wejście i wyjście
69
Tak jak klasy abstrakcyjne InputStream i OutputStream, powyższe klasy obsługują jedynie
odczyt i zapis plików na poziomie pojedynczego bajta. Oznacza to, że z obiektu fin możemy
czytać wyłącznie pojedyncze bajty oraz tablice bajtów.
byte b = (byte)fin.read();
W następnym podrozdziale przekonamy się, że korzystając z DataInputStream, moglibyśmy
wczytywać typy liczbowe:
DataInputStream din = . . .;
double x = din.readDouble();
Ale tak jak FileInputStream nie posiada metod czytających typy liczbowe, tak DataInput
Stream nie posiada metody pozwalającej czytać dane z pliku.
Java korzysta ze sprytnego mechanizmu rozdzielającego te dwa rodzaje funkcjonalności.
Niektóre strumienie wejścia (takie jak FileInputStream i strumień wejścia zwracany przez
metodę openStream klasy URL) mogą udostępniać bajty z plików i innych, bardziej egzotycznych
lokalizacji. Inne strumienie wejścia (takie jak DataInputStream) potrafią tworzyć z bajtów
reprezentację bardziej użytecznych typów danych. Programista Javy musi połączyć te dwa
mechanizmy w jeden. Dla przykładu, aby wczytywać liczby z pliku, powinien utworzyć
obiekt typu FileInputStream, a następnie przekazać go konstruktorowi DataInputStream.
FileInputStream fin = new FileInputStream( employee.dat );
DataInputStream din = new DataInputStream(fin);
double x = din.readDouble();
Wróćmy do rysunku 2.1, gdzie przedstawione są klasy FilterInputStream i FilterOutput
Stream. Ich podklasy możemy wykorzystać do zwiększania możliwości strumieni wejścia-
-wyjścia służących do operowania na zwykłych bajtach.
Różne funkcjonalności możemy dodawać poprzez zagnieżdżanie filtrów. Na przykład —
domyślnie strumienie wejścia nie są buforowane. Wobec tego każde wywołanie metody read
oznacza odwołanie się do usług systemu operacyjnego, który odczytuje kolejny bajt. Dużo
efektywniej będzie żądać od systemu operacyjnego całych bloków danych i umieszczać je
w buforze. Jeśli chcemy uzyskać buforowany dostęp do pliku, musimy skorzystać z poniższej,
monstrualnej sekwencji konstruktorów:
DataInputStream din = new DataInputStream
(new BufferedInputStream
(new FileInputStream( employee.dat )));
Zwróćmy uwagę, że DataInputStream znalazł się na ostatnim miejscu w łańcuchu konstrukto-
rów, ponieważ chcemy używać metod klasy DataInputStream i chcemy, aby korzystały one
z buforowanej metody read.
Czasami będziemy zmuszeni utrzymywać łączność ze strumieniami znajdującymi się pośrodku
łańcucha. Dla przykładu, czytając dane, musimy często podejrzeć następny bajt, aby sprawdzić,
czy jego wartość zgadza się z naszymi oczekiwaniami. W tym celu Java dostarcza klasę
PushbackInputStream.
PushbackInputStream pbin = new PushbackInputStream
(new BufferedInputStream
(new FileInputStream( employee.dat )));
Poleć książkęKup książkę70
Java. Techniki zaawansowane
Teraz możemy odczytać wartość następnego bajta:
int b = pbin.read();
i umieścić go z powrotem w strumieniu, jeżeli jego wartość nie odpowiada naszym oczeki-
waniom.
if (b != ) pbin.unread(b);
Ale wczytywanie i powtórne wstawianie bajtów to jedyne metody obsługiwane przez klasę
Pushback-InputStream. Jeżeli chcemy podejrzeć bajty, a także wczytywać liczby, potrzebujemy
referencji zarówno do PushbackInputStream, jak i do DataInputStream.
DataInputStream din = DataInputStream
(pbin = new PushbackInputStream
(new BufferedInputStream
(new FileInputStream( employee.dat ))));
Oczywiście w bibliotekach wejścia-wyjścia innych języków programowania takie udogod-
nienia jak buforowanie i kontrolowanie kolejnych bajtów są wykonywane automatycznie, więc
konieczność tworzenia ich kombinacji w języku Java wydaje się niepotrzebnym zawracaniem
głowy. Jednak możliwość łączenia klas filtrów i tworzenia w ten sposób naprawdę uży-
tecznych sekwencji strumieni wejścia-wyjścia daje nam niespotykaną elastyczność. Na przy-
kład, korzystając z poniższej sekwencji strumieni, możemy wczytywać liczby ze skompreso-
wanego pliku ZIP (patrz rysunek 2.4).
ZipInputStream zin
= new ZipInputStream(new FileInputStream( employee.zip ));
DataInputStream din = new DataInputStream(zin);
Rysunek 2.4.
Sekwencja
filtrowanych
strumieni
(Aby dowiedzieć się więcej o obsłudze formatu ZIP, zajrzyj do punktu 2.3.3, „Archiwa ZIP”, po-
święconego strumieniom plików ZIP.)
java.io.FileInputStream 1.0
FileInputStream(String name)
FileInputStream(File file)
Poleć książkęKup książkęRozdział 2. Wejście i wyjście
71
tworzy nowy obiekt typu FileInputStream, używając pliku, którego ścieżkę dostępu
zawiera parametr name, lub używając informacji zawartych w obiekcie file (klasa
File zostanie omówiona pod koniec tego rozdziału). Ścieżki dostępu są podawane
względem katalogu roboczego skonfigurowanego podczas uruchamiania maszyny
wirtualnej Java.
java.io.FileOutputStream 1.0
FileOutputStream(String name)
FileOutputStream(String name, boolean append)
FileOutputStream(File file)
FileOutputStream(File file, boolean append)
tworzy nowy strumień wyjściowy pliku określonego za pomocą łańcucha name
lub obiektu file (klasa File zostanie omówiona pod koniec tego rozdziału). Jeżeli
parametr append ma wartość true, dane dołączane są na końcu pliku, a istniejący
plik o tej samej nazwie nie zostanie skasowany. W przeciwnym razie istniejący
plik o tej samej nazwie zostanie skasowany.
java.io.BufferedInputStream 1.0
BufferedInputStream(InputStream in)
tworzy nowy buforowany strumień wejściowy typu BufferedInputStream.
Wejściowy strumień buforowany wczytuje znaki ze strumienia danych,
nie wymuszając za każdym razem dostępu do urządzenia. Gdy bufor zostanie
opróżniony, system prześle do niego nowy blok danych.
java.io.BufferedOutputStream 1.0
BufferedOutputStream(OutputStream out)
tworzy nowy buforowany strumień wyjściowy typu BufferedOutputStream.
Strumień umieszcza w buforze znaki, które powinny zostać zapisane, nie wymuszając
za każdym razem dostępu do urządzenia. Gdy bufor zapełni się lub gdy strumień
zostanie opróżniony, dane są przesyłane odbiorcy.
java.io.PushbackInputStream 1.0
PushbackInputStream(InputStream in)
PushbackInputStream(InputStream in, int size)
tworzą strumień wejściowy umożliwiający podgląd kolejnego bajta wraz z buforem
o podanym rozmiarze.
void unread(int b)
wstawia bajt z powrotem do strumienia, dzięki czemu przy następnym wywołaniu
read zostanie on ponownie odczytany.
Parametry:
zwracany bajt
b
Poleć książkęKup książkę72
Java. Techniki zaawansowane
2.2. Strumienie tekstowe
Zapisując dane, możemy wybierać pomiędzy formatem binarnym i tekstowym. Dla przykładu:
jeżeli liczba całkowita 1234 zostanie zapisana w postaci binarnej, w pliku pojawi się sekwencja
bajtów 00 00 04 D2 (w notacji szesnastkowej). W formacie tekstowym liczba ta zostanie
zapisana jako łańcuch 1234 . Mimo iż zapis danych w postaci binarnej jest szybki i efektywny,
to uzyskany wynik jest kompletnie nieczytelny dla ludzi. W poniższym podrozdziale skoncen-
trujemy się na tekstowym wejściu-wyjściu, a odczyt i zapis danych binarnych omówimy
w podrozdziale 2.3, „Odczyt i zapis danych binarnych”.
Zapisując łańcuchy znakowe, musimy uwzględnić sposób kodowania znaków. W przypad-
ku kodowania UTF-16, którego Java używa wewnętrznie, łańcuch José zostanie zakodo-
wany jako 00 4A 00 6F 00 73 00 E9 (w notacji szesnastkowej). Jednakże wiele programów
oczekuje, że pliki tekstowe będą zapisane przy wykorzystaniu innych sposobów kodowania.
W przypadku kodowania UTF-8, obecnie najczęściej stosowanego w internecie, ten sam
łańcuch znaków został zapisany jako następująca sekwencja bajtów: 4A 6F 73 C3 A9, czyli bez
bajtów 00 dla pierwszych trzech znaków oraz bez używania dwóch bajtów do zapisu znaku é.
Klasa OutputStreamWriter zamienia strumień znaków Unicode na strumień bajtów, stosując
odpowiednie kodowanie znaków. Natomiast klasa InputStreamReader zamienia strumień
wejścia, zawierający bajty (reprezentujące znaki za pomocą określonego kodowania), na obiekt
udostępniający znaki Unicode.
Poniżej przedstawiamy sposób utworzenia obiektu wejścia, wczytującego znaki z konsoli
i automatycznie konwertującego je na Unicode.
Reader in = new InputStreamReader(System.in);
Obiekt wejścia korzysta z domyślnego kodowania lokalnego systemu. W przypadku systemów
operacyjnych przeznaczonych dla komputerów stacjonarnych może to być jakiś archaiczny spo-
sób kodowania, taki jak Windows-1250 lub Mac OS Roman. Zawsze należy określać wybrany
sposób kodowania, podając jego nazwę w konstruktorze InputStreamReader, na przykład:
Reader in = new InputStreamReader(new FileInputStream( data.txt ), StandardCharsets.UTF_8);
Więcej informacji na temat kodowania znaków znajdziesz w punkcie 2.2.4, „Zbiory znaków”.
2.2.1. Zapisywanie tekstu
W celu zapisania tekstu korzystamy z klasy PrintWriter. Dysponuje ona metodami umoż-
liwiającymi zapis łańcuchów i liczb w formacie tekstowym. Dla wygody programistów ma
ona konstruktor umożliwiający zapis danych do pliku. Zatem instrukcja
PrintWriter out = new PrintWriter( employee.txt , UTF-8 );
stanowi odpowiednik instrukcji
PrintWriter out = new PrintWriter(
new FileOutputStream( employee.txt ), UTF-8 );
Poleć książkęKup książkęRozdział 2. Wejście i wyjście
73
Do zapisywania danych za pomocą obiektu klasy PrintWriter używamy tych samych metod
print, println i printf, których używaliśmy dotąd z obiektem System.out. Możemy wyko-
rzystywać je do zapisu liczb (int, short, long, float, double), znaków, wartości logicznych,
łańcuchów znakowych i obiektów.
Spójrzmy na poniższy kod:
String name = Harry Hacker ;
double salary = 75000;
out.print(name);
out.print( );
out.println(salary);
Rezultatem jego wykonania będzie wysłanie napisu
Harry Hacker 75000.0
do strumienia out. Następnie znaki zostaną skonwertowane na bajty i zapisane w pliku
employee.txt.
Metoda println automatycznie dodaje znak końca wiersza, odpowiedni dla danego systemu
operacyjnego ( \r\n w systemie Windows, \n w Unix). Znak końca wiersza możemy
pobrać, stosując wywołanie System.getProperty( line.separator ).
Jeżeli obiekt zapisu znajduje się w trybie automatycznego opróżniania, w chwili wywołania
metody println wszystkie znaki w buforze zostaną wysłane do odbiorcy (obiekty PrintWriter
zawsze są buforowane). Domyślnie automatyczne opróżnianie jest wyłączone. Automatyczne
opróżnianie możemy włączać i wyłączać przy użyciu konstruktora PrintWriter(Writer writer,
boolean autoFlush):
PrintWriter out = new PrintWriter(
new OutputStreamWriter(
new FileOutputStream( employee.txt ), UTF-8 ),
true); // automatyczne opróżnianie
Metody print nie wyrzucają wyjątków. Aby sprawdzić, czy ze strumieniem wyjścia jest
wszystko w porządku, wywołujemy metodę checkError.
Weterani Javy prawdopodobnie zastanawiają się, co się stało z klasą PrintStream
i obiektem System.out. W języku Java 1.0 klasa PrintStream obcinała znaki Unico-
de do znaków ASCII, po prostu opuszczając górny bajt (wówczas Unicode był jeszcze
kodem 16-bitowym). Takie rozwiązanie nie pozwalało na przenoszenie kodu na inne
platformy i w języku Java 1.1 zostało zastąpione przez koncepcję obiektów odczytu i zapisu.
Ze względu na konieczność zachowania zgodności z istniejącym kodem System.in, System.
out i System.err wciąż są strumieniami wejścia-wyjścia, nie obiektami odczytu
i zapisu. Ale obecna klasa PrintStream konwertuje znaki Unicode na schemat kodowa-
nia lokalnego systemu w ten sam sposób, co klasa PrintWriter. Gdy używamy metod
print i println, obiekty PrintStream działają tak samo jak obiekty PrintWriter, ale
w przeciwieństwie do PrintWriter pozwalają wysyłać bajty za pomocą metod write(int)
i write(byte[]).
Poleć książkęKup książkę74
Java. Techniki zaawansowane
java.io.PrintWriter 1.1
PrintWriter(Writer out)
PrintWriter(Writer writer)
tworzy nowy obiekt klasy PrintWriter zapisujący dane w przekazanym obiekcie
zapisu.
PrintWriter(String filename, String encoding)
PrintWriter(File file, String encoding)
tworzy nowy obiekt klasy PrintWriter zapisujący dane do podanego pliku
z wykorzystaniem określonego sposobu kodowania.
void print(Object obj)
zapisuje łańcuch zwracany przez metodę toString danego obiektu.
void print(String s)
zapisuje łańcuch Unicode.
void println(String s)
zapisuje łańcuch zakończony znakiem końca wiersza. Jeżeli automatyczne
opróżnianie jest włączone, opróżnia bufor strumienia.
void print(char[] s)
zapisuje tablicę znaków Unicode.
void print(char c)
zapisuje znak Unicode.
void print(int i)
void print(long l)
void print(float f)
void print(double d)
void print(boolean b)
zapisuje podaną wartość w formacie tekstowym.
void printf(String format, Object... args)
zapisuje podane wartości według łańcucha formatującego. Specyfikację łańcucha
formatującego znajdziesz w rozdziale 3. książki Java. Podstawy.
b
Pobierz darmowy fragment (pdf)