Консольный ввод/вывод
Консольный ввод/вывод
Для вывода на консоль мы всегда использовали метод printino класса Pnntstream, никогда не определяя экземпляры этого класса. Мы просто использовали статическое поле out класса system, которое является объектом класса PrintStream. Исполняющая система Java связывает это поле с консолью.
Кстати говоря, если вам надоело писать system.out.printino, то вы можете определить новую ссылку на system, out, например:
PrintStream pr - System.out;
и писать просто pr. printin ().
Консоль является байтовым устройством, и символы Unicode перед выводом на консоль должны быть преобразованы в байты. Для символов Latin 1 с кодами '\u0000' — '\u00FF' при этом просто откидывается нулевой старший байт и выводятся байты '0х00' —'0xFF'. Для кодов кириллицы, которые лежат в диапазоне '\u0400 1 —'\u04FF 1 кодировки Unicode, и других национальных алфавитов производится преобразование по кодовой таблице, соответствующей установленной на компьютере л окал и. Мы обсуждали это в главе 5.
Трудности с отображением кириллицы возникают, если вывод на консоль производится в кодировке, отличной от локали. Именно так происходит в русифицированных версиях MS Windows NT/2000. Обычно в них устанавливается локаль с кодовой страницей СР1251, а вывод на консоль происходит в кодировке СР866.
В этом случае надо заменить Printstream, который не может работать с сим- , вольным потоком, на Printwriter и "вставить переходное кольцо" между потоком символов Unicode и потоком байтов system, out, выводимых на консоль, в виде объекта класса OutputstreamWriter. В конструкторе этого объекта следует указать нужную кодировку, в данном случае, СР866. Все это можно сделать одним оператором:
PrintWriter pw = new PrintWriter(
new OutputstreamWriter(System.out, "Cp866"), true);
Класс Printstream буферизует выходной поток. Второй аргумент true его конструктора вызывает принудительный сброс содержимого буфера в выходной поток после каждого выполнения метода printin(). Но после print() буфер не сбрасывается! Для сброса буфера после каждого print() надо писать flush(), как это сделано в листинге 18.2.
Замечание
Методы класса PrintWriter по умолчанию не очищают буфер, а метод print () не очищает его в любом случае. Для очистки буфера используйте метод flush().
После этого можно выводить любой текст методами класса PrintWriter, которые просто дублируют методы класса Printstream, и писать, например,
pw.println("Это русский текст");
как показано в листинге 18.1 и на Рисунок 18.3.
Следует заметить, что конструктор класса PrintWriter, в котором задан байтовый поток, всегда неявно создает объект класса OutputstreamWriter с локальной кодировкой для преобразования байтового потока в символьный поток.
Ввод с консоли производится методами read о класса inputstream с помощью статического поля in класса system. С консоли идет поток байтов, полученных из scan-кодов клавиатуры. Эти байты должны быть преобразованы в символы Unicode такими же кодовыми таблицами, как и при выводе на консоль. Преобразование идет по той же схеме — для правильного ввода кириллицы удобнее всего определить экземпляр класса BufferedReader, используя в качестве "переходного кольца" объект класса inputstreamReader:
BufferedReader br = new BufferedReader(
new InputstreamReader(System.an, "Cp866"));
Класс BufferedReader переопределяет три метода read о своего суперкласса Reader. Кроме того, он содержит метод readLine ().
Метод readLine о возвращает строку типа string, содержащую символы входного потока, начиная с текущего, и заканчивая символом '\п' и/или '\r'. Эти символы-разделители не входят в возвращаемую строку. Если во входном потоке нет символов, то возвращается null.
В листинге 18.1 приведена программа, иллюстрирующая перечисленные методы консольного ввода/вывода. На Рисунок 18.3 показан вывод этой программы.