Главная страница

Java. Полное руководство. 8-е издание. С. Н. Тригуб Перевод с английского и редакция


Скачать 25.04 Mb.
НазваниеС. Н. Тригуб Перевод с английского и редакция
АнкорJava. Полное руководство. 8-е издание.pdf
Дата28.02.2017
Размер25.04 Mb.
Формат файлаpdf
Имя файлаJava. Полное руководство. 8-е издание.pdf
ТипДокументы
#3236
страница56 из 90
1   ...   52   53   54   55   56   57   58   59   ...   90
6 1 4 Часть II. Библиотека Java
// Использование буферизованного ввода Эта программа использует оператор try-с-ресурсами. Требует JDK 7.
import java.io.*;
class BufferedlnputStreamDemo {
public static void main(String a r g s []) {
String s = "This is a © copyright symbol " +
"but this is © not.Xn";
byte buf[] = s.getBytes();
ByteArraylnputStream in = new ByteArraylnputStream(buf);
int с ;
boolean marked = false;
// Использование Try-с-ресурсами для управления файлами
try (
Bufferedlnputstream f = new BufferedlnputStream(in) )
{
while (
(c = f.readO) != -1) {
switch(c) {
case
:
if (Imarked) {
f.mark(32);
marked = true;
} else {
marked = false;
}
break;
case ';':
if (marked) {
marked = false;
System.out.print("(c)");
} else
System.out.print((char)
c ) ;
break;
case '
':
if (marked) {
marked = false;
f .reset ();
System.out.print("&");
} else
System.out.print((char)
c ) ;
break;
default:
if (imarked)
System.out.print((char)
c ) ;
break;
}
}
} c a t c h (IOException e) {
System.out.println("I/O Error: " + e) Обратите внимание на то, что этот пример использует метод mar k ( 32 ), что сохраняет метку для чтения следующих 32 байт (чего достаточно для любых ссылок насущности. Вот как выглядит вывод, создаваемый этой программой is ас Глава 19. Ввод-вывод: пакет java.io
6 1 Класс Класс
BufferedOutputStream подобен любому классу
OutputStream, за исключением дополнительного метода flush(), используемого для обеспечения записи данных в буферизируемый поток. Поскольку назначение класса
Buf f eredOutputStream
— увеличивать производительность за счет сокращения количества физических записей данных, вам может понадобиться вызывать метод f lush ()
, чтобы инициировать немедленную запись всех данных из буфера.
В отличие от буферизованного ввода, буферизованный вывод не предоставляет дополнительной функциональности. Буферы вывода в Java нужны для повышения производительности. Вот два доступных конструктора этого класса

выходнойПоток)
BufferedOutputStream(OutputStream
выходнойПоток,
int
размерБуфера)
Первая форма создает буферизованный поток, используя размер буфера поумол­
чанию. Во второй форме размер буфера передается параметром
размерБуфера.
Класс Одним из новшеств в буферизации является реализация вталкивания (push- back) . Вталкивание используется с потоками ввода, чтобы обеспечить чтение байта с последующим его возвратом (те. втолкнуть) в поток. Класс
PushbacklnputStream реализует эту идею. Он представляет механизм для того, чтобы заглянуть во входной потоки увидеть, что оттуда поступит в следующий раз, не извлекая информации.
Класс
PushbacklnputStream имеет следующие конструкторы

входнойПоток)
PushbacklnputStream(InputStream
входнойПоток,
int
колБайтов)
Первая форма создает объект потока, позволяющий вернуть один байт во входной поток. Вторая форма создает поток, оснащенный буфером вталкивания длиной
колБайтов. Это позволяет вернуть во входной поток множество байтов.
Помимо знакомых уже методов класса
InputStream, класс
Pushback­
lnputStream предлагает метод unread ().
void unread(int б unread(byte буфер буфер int смещение int
количБайтов)
Первая форма вталкивает в поток младший байт б. После этого он вновь будет следующим байтом, возвращаемым последующим вызовом метода read ()
. Вторая форма вталкивает байты в буфер Третья же форма вталкивает
количБайтов байт, начиная с позиции смещение, в буфер Исключение
IOException передается в случае попытки втолкнуть байт, когда буфер переполнен.
Рассмотрим пример, демонстрирующий, как синтаксический анализатор языка программирования может использовать класс
PushbacklnputStream и метод unread
(), чтобы справиться с различием между операциями сравнения (= = ) и присваивания (=).
/
'
/ Демонстрация применения unread () .
// Эта программа использует оператор try-с-ресурсами. Требует JDK 7.
import java.io.*;
class PushbacklnputStreamDemo {
public static void main(String a r g s []) {
String s = "if (a =
= 4) a = 0;\n";
byte buf[] = s .getBytes();
ByteArraylnputStream in = new ByteArraylnputStream(buf);

6 1 Часть II. Библиотека Java
int с ;
try (
PushbacklnputStream f = new PushbacklnputStream(in) )
{
while (
(c = f.readO) != -1) {
switch(c) {
case '=':
if (
(c = f.readO )
== '
= '
)
System.out.print(".eq.");
else {
System.out.print("<-");
f .unread(c);
}
break;
default:
System.out.print((char) c ) ;
break;
}
}
} c a t c h (IOException e) {
System.out.println("I/O Error: " + e ) Ниже показан вывод этого примера. Обратите внимание на то, что 11 = =" заменяется на " . e q . ", а " =" — на "<- ".
if (a .eq. 4) а- Внимание Класс
PushbacklnputStream обладает побочным эффектом — он делает невозможным использование методов

mark
() и
reset
() потока класса
inputstream, использованного для его создания. Применяйте метод

markSupported
( ) , чтобы проверить каждый поток на предмет возможности использования методов
mark () и
reset (Класс S e q u e n c e ln p u t S t r e a Класс
SequencelnputStream позволяет соединять вместе несколько экземпляров класса
Inputstream. Создание объекта класса
SequencelnputStream отличается от создания объекта класса
Inputstream. Конструктор класса
SequencelnputStream принимает в качестве аргумента либо пару объектов класса
Inputstream, либо интерфейс
Enumeration из объекта класса
Inputstream.
SequencelnputStream(Inputstream первый Inputstream второй)
SequencelnputStream(Enumeration
перечПотоков)
Во время работы класс выполняет запросы на чтение из первого объекта класса
Inputstream и до конца, а затем переключается на второй. В случае интерфейса
Enumeration работа продолжится по всем объектам классам
Inputstream, пока не будет достигнут конец последнего. По достижении конца каждого файла, связанный с ним поток закрывается. Закрытие потока, созданного объектом класса
SequencelnputStream, приводит к закрытию всех открытых потоков.
Вот простой пример использования класса
SequencelnputStream для вывода содержимого двух файлов. В демонстрационных целях эта программа использует традиционную методику закрытия файла. В качестве упражнения вы могли бы попробовать изменить его так, чтобы использовать оператор try
- с - ресурсами Демонстрация последовательного ввода Эта программа использует оператор try-с-ресурсами. Требует JDK 7.

Глава 19. Ввод-вывод: пакет java.io
6 1 7
import java.io.*;
import java.util.*;
class InputStreamEnumerator implements Enumeration {
private Enumeration files;
public InputStreamEnumerator(Vector files) {
this.files = files.elements();
}
public boolean hasMoreElements() {
return files.hasMoreElements();
}
public Filelnputstream nextElement() {
try {
return new Filelnputstream(files.nextElement().toString());
} catch (IOException e) {
return null;
}
}
}
class SequencelnputStreamDemo {
public static void main(String a r g s []) {
int с ;
Vector files = new Vector();
files.addElement("filel.txt")
files.addElement("file2.txt")
files.addElement("file3.txt") ,
InputStreamEnumerator ise = new InputStreamEnumerator(files);
InputStream input = new SequencelnputStream(ise);
try {
while ((c = input.r e a d ()) != -1)
System.out.print((char)
c ) ;
} catch(NullPointerException e) {
System.out.println("Error Opening File.");
} c a t c h (IOException e) {
System.out.println("I/O Error: " + e) ;
} finally {
try {
input.c l o s e ();
} c a t c h (IOException e) {
System.out.println("Error Closing Этот пример создает объект класса
Vector и затем добавляет к нему три имени файла. Затем этот вектор с именами передается классу
InputStreamEnumerator, предназначенному служить оболочкой вектора, в которой элементы возвращаются не в виде имен файлов, а в виде открытых объектов класса
Filelnputstream, созданных по этим именам. Объект класса
SequencelnputStream открывает каждый файл по очереди, и таким образом этот пример выводит содержимое этих файлов.
О братите внимание на то, что если файл в методе nextElement
() не может быть открыт, возвращается значение null. В результате передается исключение
NullPointerException, обрабатываемое в функции main ().

6 1 Часть II. Библиотека Класс P r i n t S t r e a Класс
PrintStream предоставляет все возможности вывода, которыми мы пользуемся с дескриптором
System.out файла класса
System с самого начала нашей книги. Это делает класс
PrintStream одним из наиболее часто используемых классов Java. Он реализует интерфейсы
Appendable, AutoCloseable,
Closeable и Класс
PrintStream определяет несколько конструкторов. Для начала рассмотрим перечисленные ниже

выходнойПоток)
PrintStream(OutputStream
выходнойПоток,
boolean
сбросПриНовойСтроке)
PrintStream(OutputStream
выходнойПоток,
boolean
сбросПриНовойСтроке,
S t r i n g наборСимволов)
throws Здесь
выходнойПоток указывает открытый объект класса
OutputStream, который будет принимать вывод. Параметр
сбросПриНовойСтроке управляет тем, будет ли выходной буфер автоматически сбрасываться при каждой записи символа новой строки п, записи байтового массива либо вызове метода println (). Если аргумент
сбросПриНовойСтроке равен значению true, происходит автоматический сброс. Если же он равен значению f a l s e , сброс будет неавтоматиче­
ским. Первый конструктор не включает автоматический сброс. Вы можете задать кодировку символов, передав ее имя в параметре
наборСимволов.
Следующий набор конструкторов предоставляет простые способы создания объекта класса
PrintStream, который пишет свой вывод в файл

выходнойФайл)
throws FileNotFoundException
PrintStream(File
выходнойФайл,
String
наборСимволов)
throws FileNotFoundException, UnsupportedEncodingException
PrintStream(String
имяВыходногоФайла)
throws FileNotFoundException
PrintStream(String
имяВыходногоФайла,
String
наборСимволов)
throws FileNotFoundException, UnsupportedEncodingException Они позволяют создавать объект класса
PrintStream на основе объекта класса
File либо имени файла. В любом случае файл создается автоматически. Любой существующий файл стем же именем уничтожается. Будучи созданным, объект класса
PrintStream управляет всем выводом в указанный файл. Кодировку символов можно указать в параметре
наборСимволов.
Класс
PrintStream поддерживает методы print
() и println
() для всех типов, включая тип
Object. Если аргумент не относится к элементарному типу, то методы класса
PrintStream вызывают метод toString
() объекта, а затем отображают его результат.
Не так давно (споявлением версии JDK 5) вкласс
Print
Stream был добавлен метод print f ()
. Он позволяет задать точный формат вывода записываемых данных. Метод print f
() использует класс
Formatter описанный в главе 18) для форматирования данных. Затем он выводит эти данные в вызывающий поток. Хотя форматирование может выполняться вручную за счет непосредственного использования класса
Formatter, все же метод print f () существенно упрощает процесс. Он является аналогом функции C/C++ print f
(), облегчая преобразование существующего кода C/C++ в Java. Откровенно говоря, метод print f
() — весьма полезное дополнение к Java API, поскольку значительно упрощает вывод форматированных данных на консоль. Метод print f
() имеет следующие общие формы p r i n t f (String

формСтрока,
Object ... аргументы printf(Locale регион
формСтрока,
Object ... аргументы)
Первая версия записывает аргументы в стандартный вывод в формате, указанном
формСтрока
, используя локальные установки по умолчанию. Вторая версия
Глава 19. Ввод-вывод: пакет java.io
6 1 позволяет указать региональные данные. Обе возвращают вызывающий объект класса В общем случае метод printf
() подобен методу format
( ), который определен в классе
Formatter. Параметр
формСтрока состоит из элементов двух типов. Первый тип содержит символы, которые просто копируются в выходной буфер, второй тип — спецификаторы формата, определяющие способ отображения последующих аргументов — аргументы За полной информацией о форматированном выводе, включая описание спецификаторов формата, обращайтесь к описанию класса
Formatter в главе Поскольку поток
System.out имеет тип
PrintStream, вы можете вызывать метод printf
() с потоком
System, out. Поэтому метод printf
() может служить в качестве замены метода println(), когда необходимо выдавать на консоль форматированный вывод. Например, в следующей программе метод printf
() используется для вывода числовых значений в различных форматах. До JDK 5 такое форматирование требовало существенной работы. С появлением метода printf
() оно значительно упростилось Демонстрация применения pr i n t f О .

class PrintfDemo {
public static void main(String a r g s []) Ниже следуют некоторые числовые значения " +в различных форматах.\п");
System.out.printf("Различные целочисленные форматы ");
System.out.printf("%d %(d %+d %05d\n",
3, -3, 3, Формат с плавающей точкой по умолчанию п, Плавающая точка с запятыми % /f\n"/
1234567.123);
System.out.p r i n t f (Отрицательная плавающая точка по умолчанию
%,f\n", -Параметры отрицательной плавающей точки:
%,(f\п", -1234567.123);
System.out.p r Строка из положительных и отрицательных
значений:\п");
System.out.printf("% ,.2f\n% Вывод этой программы.
Ниже следуют некоторые числовые значения в различных форматах.
Различные целочисленные форматы 3 (3) +3 Формат с плавающей точкой по умолчанию 123 45 67.123 000 Плавающая точка с запятыми Отрицательная плавающая точка по умолчанию -1,234,567.123000
Параметры отрицательной плавающей точки (Строка из положительных и отрицательных значений:

1,234,567.12
-1,234,567.12
В классе
PrintStream определен также метод format ()
. Вот его общие формы

6 2 Часть II. Библиотека Java
PrintStream format(String
формСтрока,
Object ... аргументы format(Locale регион
формСтрока,
Object ...
аргументы)
Он работает точно также, как метод print f (Классы
DataOutputStream и Эти классы позволяют писать или читать элементарные данные в потоки из него. Они реализуют интерфейсы
DataOutput и
Datalnput соответственно. Эти интерфейсы определяют методы, преобразующие элементарные значения в форму последовательности байтов. Такие потоки облегчают сохранение в файле двоичных данных, таких как целочисленные значения или значения с плавающей точкой. Рассмотрим здесь и то, и другое.
Класс
DataOutputStream расширяет класс
FilterOutputStream, который, в свою очередь, расширяет класс
OutputStream. Кроме реализации интерфейса, класс
DataOutputStream реализует также интерфейсы
AutoCloseable, Closeable и
Flushable. В классе
DataOutputStream определен следующий конструктор

выходнойПоток)
Здесь
выходнойПоток определяет выходной поток, в который будут записаны данные. Когда поток класса
DataOutputStream закрывается (при вызове метода close ()
), основной поток, определенный аргументом
выходнойПоток
, также закрывается автоматически.
Класс
DataOutputStream поддерживает все методы, определенные его супер­
классами. Однако он реализует методы, определенные интерфейсом
DataOutput, которые и делают его интересным. Интерфейс определяет методы, преобразующие значения элементарных типов в последовательности байтов, аза тем записывающие их в лежащий в основе поток. Вот образцы этих методов void writeDouble(double значение throws IOException
final void writeBoolean(boolean значение throws IOException
final void writelnt(int значение throws Здесь значение

это значение, записываемое в поток.
Класс
Datalnput
St ream
— это дополнение класса
DataOutputStream. Он расширяет класс
FilterlnputStream, который, в свою очередь, расширяет класс
Inputstream. Кроме реализации интерфейса
Datalnput, класс
Datalnput
Stream реализует также интерфейсы
AutoCloseable и
Closeable. Он определяет только один следующий конструктор

входнойПоток)
Здесь
входнойПоток определяет входной поток, откуда будут читаться данные. Когда поток класса
DatalnputStream закрывается (при вызове метода close
()), основной поток, определенный аргументом
входнойПоток
, также закрывается автоматически.
Как и класс
DataOutputStream, класс
DatalnputStream поддерживает все методы своих суперклассов, наряду с методами, определенными интерфейсом
Datalnput, что и делает его уникальным. Эти методы читают последовательность байтов и преобразуют их в значения элементарных типов. Ниже показаны образцы этих методов double readDouble( )
1   ...   52   53   54   55   56   57   58   59   ...   90


написать администратору сайта