logo
Хабибуллин

Консольный ввод/вывод

Для вывода на консоль мы всегда использовали метод println() класса PrintStream, никогда не определяя экземпляры этого класса. Мы просто использовали статическое поле out класса System, которое является объектом класса PrintStream. Исполняющая система Java связывает это поле с консолью.

Кстати, если вам надоело писать System.out.println(), то вы можете определить новую ссылку на System.out, например:

PrintStream pr = System.out;

и писать просто pr.println().

Консоль является байтовым устройством, и символы Unicode перед выводом на консоль должны быть преобразованы в байты. Для символов Latin 1 с кодами '\u0000''\u00FF' при этом просто откидывается нулевой старший байт и выводятся байты '0x00''0xFF'. Для кодов кириллицы, которые лежат в диапазоне '\u0400''\u04FF' кодировки Unicode, и других национальных алфавитов производится преобразование по кодовой таблице, соответствующей установленной на компьютере локали. Мы уже обсуждали это в главе 5.

Трудности с отображением кириллицы возникают, если вывод на консоль производится в кодировке, отличной от локали. Именно так происходит в русифицированных версиях MS Windows. Обычно в них устанавливается локаль с кодовой страницей CP1251, а вывод на консоль происходит в кодировке CP866.

В этом случае надо заменить PrintStream, который не может работать с символьным потоком, на PrintWriter и "вставить переходное кольцо" между потоком символов Unicode и потоком байтов System.out, выводимых на консоль, в виде объекта класса OutputStreamWriter. В конструкторе этого объекта следует указать нужную кодировку, в данном случае CP866. Все это можно сделать одним оператором:

PrintWriter pw = new PrintWriter(

new OutputStreamWriter(System.out, "Cp866"), true);

Класс PrintWriter буферизует выходной поток. Второй аргумент true его конструктора вызывает принудительный сброс содержимого буфера в выходной поток после каждого выполнения метода println(). Но после выполнения метода print() буфер не сбрасывается! Для сброса буфера после каждого обращения к методу print() надо обращаться к методу flush().

ЗАМЕЧАНИЕ

Методы класса PrintWriter по умолчанию не очищают буфер, а метод print() не очищает его в любом случае. Для очистки буфера используйте метод flush().

После этого можно выводить любой текст методами класса PrintWriter, которые просто дублируют методы класса PrintStream, и писать, например,

pw.println("Это русский текст");