Чтение онлайн

ЖАНРЫ

Философия Java3

Эккель Брюс

Шрифт:

Так как класс должен упростить процесс чтения и записи файлов, все исключения IOException преобразуются в RuntimeException, чтобы пользователю не пришлось создавать блоки try/catch. Возможно, вы предпочтете создать другую версию, которая возвращает IOException вызывающей стороне.

В методе main выполняется небольшой тест, позволяющий удостовериться в правильной работе методов. Несмотря на то что кода в этом классе немного, его применение позволит сэкономить вам уйму времени и сделать вашу жизнь проще, в чем вы еще будете иметь возможность убедиться чуть позже.

Стандартный ввод/вывод

Термин

«стандартный ввод/вывод» возник еще в эпоху UNIX (и в некоторой форме имеется и в Windows, и во многих других операционных системах). Он означает единственный поток информации, используемый программой. Вся информация программы приходит из стандартного ввода (standard input), все данные записываются в стандартный вывод (standard output), а все ошибки программы передаются в стандартный поток для ошибок (standard error). Значение стандартного ввода/вывода состоит в том, что программы легко соединять в цепочку, где стандартный вывод одной программы становится стандартным вводом другой программы. Это мощный инструмент.

Чтение из стандартного потока ввода

Следуя модели стандартного ввода/вывода, Java определяет необходимые потоки для стандартного ввода, вывода и ошибок: System.in, System.out и System.err. На многих страницах книги вы не раз могли наблюдать процесс записи в стандартный вывод System.out, для которого уже надстроен класс форматирования данных PrintStream. Поток для ошибок System.err схож со стандартным выводом, а стандартный ввод System.in представляет собой «низкоуровневый» поток InputStream без дополнительных надстроек. Это значит, что потоки System, out и System.err можно использовать напрямую, в то время как стандартный ввод System.in желательно надстраивать.

Обычно чтение осуществляется построчно, методом readLine, поэтому имеет смысл буферизовать стандартный ввод System.in посредством BufferedReader. Чтобы сделать это, предварительно следует конвертировать поток System.in в считывающее устройство Reader посредством класса-преобразователя InputStreamReader. Следующий пример просто отображает на экране последнюю строку, введенную пользователем (эхо-вывод):

//• io/Echo java

// Чтение из стандартного ввода

// {RunByHand}

import java io.*;

public class Echo {

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

BufferedReader stdin = new BufferedReaderC new InputStreamReader(System in)),

String s,

while((s = stdin readLineO) != null && s.lengthO! = 0)

System.out.printin(s); // Пустая строка или нажатие Ctrl+Z завершает программу

}

} ///-

Присутствие спецификации исключений объясняется тем, что метод readLineO может возбуждать исключение IOException. Снова обратите внимание, что поток System.in обычно буферизуется, впрочем, как и большинство потоков.

Замена System.in на PrintWriter

Стандартный вывод System.out является объектом PrintStream, который, в свою очередь, наследует от базового класса OutputStream. В классе PrintWriter имеется конструктор, который принимает в качестве аргумента

выходной поток Output-Stream. Таким образом, вы можете преобразовать поток стандартного вывода System.out в символьно-ориентированный поток PrintWriter:

II. io/ChangeSystemOut.java

// Преобразование System out в символьный поток PrintWriter import java io *.

public class ChangeSystemOut {

public static void main(String[] args) {

PrintWriter out = new PrintWriterCSystem.out, true); out printlnC"Hello, world");

}

} /* Output. Hello, world */// ~

Важно использовать конструктор класса PrintWriter с двумя аргументами, и передать во втором аргументе true, чтобы обеспечить автоматический сброс буфера на печать, иначе можно вовсе не увидеть никакого вывода.

Перенаправление стандартного ввода/вывода

Класс System позволяет вам перенаправить стандартный ввод, вывод и поток ошибок. Для этого предусмотрены простые статические методы: setln(InputStream); setOut(PrintStream); setErr(PrintStream).

Перенаправление стандартного вывода особенно полезно тогда, когда ваша программа выдает слишком много сообщений сразу и вы попросту не успеваете читать их, поскольку они заменяются новыми сообщениями. Перенаправление ввода удобно для программ, работающих с командной строкой, в которых необходимо поддержать некоторую последовательность введенных пользователем данных. Вот простой пример, показывающий, как использовать эти методы:

//: io/Redirecting.java

// Перенаправление стандартного ввода/вывода.

import java io.*.

public class Redirecting {

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

PrintStream console = System.out; BufferedlnputStream in = new BufferedlnputStreamC new FilelnputStreamCRedirecting.java")); PrintStream out = new PrintStreamC new BufferedOutputStreamC

new FileOutputStream("test.out")));

System.setln(in); System.setOutCout); System.setErr(out);

BufferedReader br = new BufferedReaderC

new InputStreamReader(System.in));

String s;

while((s = br.readLineO) != null)

System.out.printin(s); out closeO, // He забывайте! System.setOut(console);

}

} ///.-

Программа присоединяет стандартный ввод к файлу и перенаправляет, стандартный ввод и поток для ошибок в другие файлы. Обратите внимание

на сохранение ссылки на исходный объект System.out в начале программы и его восстановление в конце.

Перенаправление основано на байтовом, а не на символьном вводе/выводе, поэтому в примере используются InputStream и OutputStream, а не их символь-но-ориентированные эквиваленты Reader и Writer.

Новый ввод/вывод (nio)

При создании библиотеки «нового ввода/вывода» Java, появившейся в JDK 1.4 в пакетах java.nio.*, ставилась единственная цель: скорость. Более того, «старые» пакеты ввода/вывода были переписаны с учетом достижений nio, с намерением использовать преимущества повышенного быстродействия, поэтому улучшения вы получите, даже если не будете писать явный т'о-код. Подъем производительности просматривается как в файловом вводе/выводе, который мы здесь рассматриваем, так и в сетевом вводе/выводе.

Поделиться с друзьями: