ITI0011RUS:IO

Allikas: Kursused
Mine navigeerimisribale Mine otsikasti

Взаимодействие программы с внешним миром происходит через т.н вввод-вывод, а соответствующие операции называются операциями ввода-вывода (Input/Output Operations) или просто IO. Ввод отвечает за поступление в программу исходных данных, а вывод отвечает за то, что делать с результатами работы программы.

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

В Java независимо от того откуда осуществляется ввод/вывод (из устройства, или из файла), все данные записываются в т.н. потоки. Эти потоки являются объектами Java, и с потоками мы работаем, когда нам нужно обработать ввод или записать что-то в вывод. У каждого процесса в системе есть 3 связанных с ним т.н. стандартных потока:

  • Стандартный поток ввода - STDIN (Standard Input). В Java - объект System.in
  • Стандартный поток вывода - STDOUT (Standard Output). В Java - объект System.out
  • Стандартный поток ошибок - STDERR (Standard Error). В Java - объект System.err

По умолчанию стандартный поток ввода связан с клавиатурой, стандартный поток вывода и стандартный поток ошибок связан с монитором. Отличие этих "стандартных" потоков от остальных потоков в том, что они открываются операционной системой при старте процесса, и закрываются при завершении процесса.

Программист также может создавать произвольное количество своих потоков (максимальное количество потоков в системе, конечно же, не бесконечно, но оно достаточно большое, чтобы не задумываться об этом). Например, для того, чтобы прочитать файл, программист может создать поток чтения из файла. Поток, который создан не системой, а программистом - находится полностью под ответственностью программиста. После открытия потока, например, задачачей программиста является корректно закрыть поток после окончания работы с ним. Стандартные потоки операционная система открывает и закрывает сама - нам не следует об этом беспокоиться. Нужно только помнить, что не следует открывать стандартные потоки, поскольку эти 3 потока уже открыты системой для каждого процесса.

Работа с потоками в Java

Для работы с потоками в Java предусмотрены т.н. читатели (объекты Reader), и писатели (объекты Writer). Вся работа с потоками в сущности сводится к созданию соответствующих объектов Reader либо Writer и работе с ними.

Существует различные типы потоков для различных типов данных. Потоки грубо говоря делятся на бинарные и символьные. Бинарные потоки воспринимают ввод на уровне байтов и из-за этого эти потоки позволяют нам сделать с ними ограниченное количество действий - например, считать один байт, или считать n байт в массив. Такие потоки предназначены для чтения бинарных данных и последующей машинной обработки - они не предназначены для восприятия человеком. Символьные потоки воспринимают информацию уровнем выше - для них ввод это не просто последовательность байт, а осмысленные символы, которые можно прочитать. Символы также подразделяются на печатные и непечатные. Строки состоят из печатных символов, а символ переноса строки, например, непечатный символ. Символьные потоки могут рассмотреть в непрерывном потоке байт строки (как последовательность символов, которая оканчивается символами окончания строки), что позволяет нам работать с таким потоком на уровне строк - прочитать строку, либо прочитать все строки из потока.

Чтение пользовательского ввода с клавиатуры

Для чтения пользовательского ввода с клавиатуры используется читатель символьного потока, который называется BufferedReader. Этот читатель, однако, не является самодостаточным. По сути, это обёртка вокруг читателя бинарных потоков InputStreamReader.

Создание объекта BufferedReader по причинам, описанным выше, происходит в два этапа - сначала создается читатель бинарных данных InputStreamReader, который передается объекту BufferedReader.

<source lang="java"> InputStreamReader is = new InputStreamReader(System.in); BufferedReader br = new BufferedReader(is); </source>

То же самое можно сделать одной строкой: <source lang="java"> BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); </source>