Что такое метод ввода с клавиатуры
О бычно программа работает по такой схеме: получает входные данные → обрабатывает их → выдает результат. Ввод может поступать как непосредственно от пользователя через клавиатуру, так и через внешний источник (файл, база данных).
В стандартной библиотеке Python 3 есть встроенная функция input() (в Python 2 это raw_input() ), которая отвечает за прием пользовательского ввода. Разберемся, как она работает.
Чтение ввода с клавиатуры
Функция input([prompt]) отвечает за ввод данных из потока ввода:
- При вызове функции input() выполнение программы приостанавливается до тех пор, пока пользователь не введет текст на клавиатуре (приложение может ждать бесконечно долго).
- После нажатия на Enter , функция input() считывает данные и передает их приложению (символ завершения новой строки не учитывается).
- Полученные данные присваиваются переменной и используются дальше в программе.
input() всегда возвращает строку :
Также у input есть необязательный параметр prompt – это подсказка пользователю перед вводом:
name = input("Введите имя: ") print(f"Привет, !") > Введите имя: Вася > Привет, Вася!
📃 Более подробное описание функции из документации:
def input([prompt]): """ Read a string from standard input. The trailing newline is stripped. The prompt string, if given, is printed to standard output without a trailing newline before reading input. If the user hits EOF (*nix: Ctrl-D, Windows: Ctrl-Z+Return), raise EOFError. On *nix systems, readline is used if available. """ pass
Преобразование вводимые данные
Данные, введенные пользователем, попадают в программу в виде строки, поэтому и работать с ними можно так же, как и со строкой. Если требуется организовать ввод цифр, то строку можно преобразовать в нужный формат с помощью функций явного преобразования типов.
☝️ Важно : если вы решили преобразовать строку в число, но при этом ввели строку (например: test), возникнет ошибка:
На практике такие ошибки нужно обрабатывать через try except . В примере ниже пользователь будет вводить данные до тех пор, пока они успешно не преобразуются в число.
def get_room_number(): while True: try: num = int(input("Введите номер комнаты: ")) return num except ValueError: print("Вы ввели не число. Повторите ввод") room_number = get_room_number() print(f"Комната успешно забронирована!") > Введите номер комнаты: test > Вы ввели не число. Повторите ввод > Введите номер комнаты: 13 > Комната 13 успешно забронирована!
Input() → int
Для преобразования в целое число используйте функцию int() . В качестве аргумента передаются данные которые нужно преобразовать, а на выходе получаем целое число:
То же самое можно сделать в одну строку: age = int(input("Введите ваш возраст: ")) .
Input() → float
Если нужно получить число с плавающей точкой (не целое), то его можно получить с помощью функции float() .
Input() → list (список)
Если в программу вводится информация, которая разделяется пробелами, например, "1 word meow", то ее легко преобразовать в список с помощью метода split() . Он разбивает введенные строки по пробелам и создает список:
💭 Обратите внимание, что каждый элемент списка является строкой. Для преобразования в число, можно использовать int() и цикл for. Например, так:
Ввод в несколько переменных
Если необходимо заполнить одним вводом с клавиатуры сразу несколько переменных, воспользуйтесь распаковкой:
В этом примере строка из input() разбивается по пробелу функцией split() . Далее применяется синтаксис распаковки – каждый элемент списка попадает в соответствующую переменную.
Все переменные после распаковки будут строкового типа. Преобразовать их (например в int) можно так:
☝️ Важно : не забывайте обрабатывать ошибки:
В этом руководстве вы узнали, как принимать данные от пользователя, введенные с клавиатуры, научились преобразовывать данные из input и обрабатывать исключения.
Метод ввода (или редактор метода ввода , обычно сокращенно IME ) представляет собой операционную систему компонент или программа , которая позволяет пользователям создавать символы изначально не доступные на своих устройствах ввода , используя последовательность символов (или операции мыши), которые изначально доступны на их входе устройств. Использование метода ввода обычно необходимо для языков, в которых графем больше, чем клавиш на клавиатуре.
Например, на компьютере это позволяет пользователю латинской клавиатуры вводить китайские , японские , корейские и индийские символы. На портативных устройствах он позволяет пользователю набирать текст на цифровой клавиатуре для ввода символов латинского алфавита (или любых других букв алфавита) или касаться экрана для ввода текста. В некоторых операционных системах метод ввода также используется для определения поведения мертвых клавиш .
СОДЕРЖАНИЕ
Реализации
Первоначально этот термин был придуман для вычислений CJK (китайский, японский и корейский), но сейчас этот термин иногда используется в общем для обозначения программы, поддерживающей ввод на любом языке. Чтобы проиллюстрировать, в системе X Window возможность ввода латинских символов с диакритическими знаками также называется методом ввода.
В Windows XP или более поздних версиях Windows метод ввода или IME также называется обработчиком ввода текста , который реализуется API платформы текстовых служб .
Взаимосвязь методологии и реализации
Хотя термин редактор метода ввода первоначально использовался для Microsoft Windows , его использование теперь получило признание в других операционных системах, особенно когда важно различать компьютерный интерфейс и реализацию методов ввода или среди самих методов ввода редактирование функциональность программы или компонента операционной системы, обеспечивающего метод ввода, и общая поддержка методов ввода в операционной системе. Этот термин, например, получил широкое распространение в операционной системе Linux; он также используется в Mac OS.
Прямой ввод-вывод "на среднем уровне" позволяет вводить и выводить текстовые символы в файл , на консоль , модем , удалённый терминал . При этом в MS-DOS он организован при помощи механизма прерываний. Для иллюстрации "прямого ввода" будут приведены функции прямого ввода с консоли на языках Ассемблер и Си .
5.1. Введение. Общие сведения о клавиатуре
Клавиатура - это не просто "доска с клавишами" (дословный перевод английского названия " keyboard "). Помимо механической части (собственно клавиш и контактов) она включает в себя сложную топологию проводников, и даже собственный микропроцессор - контроллер .
Задачи, решаемые этим микропроцессором, следующие:
- Реагировать на нажатие клавиш или комбинации клавиш;
- Реагировать на "длительное" нажатие на клавишу, и осуществлять соответствующие действия;
- По положению клавиш генерировать специальный скен-код клавиши (см. раздел 5.1.1.);
- В соответствии с "таблицей символов" (codepage) преобразовывать скен-код клавиши в ASCII символ, ей соответствующей;
Примечание: некоторые "серые" ( управляющие) клавиши не генерируют символы, а используются только для управления компьютером. В этом случае для них ASCII символ не генерируется (записывается в 0).
Видите, как всё сложно.… Теперь разберёмся с остальным.
5.1.1. Понятие о скэн-кодах клавиш
При нажатии клавиши на клавиатуре генерируется её скен-код. Скен-код можно считать "номером клавиши" на клавиатуре. Однако это не совсем так. Например, если скен код клавиши "F10" равен "68", то тот же код клавиши с нажатой клавишей "Shift" будет равен "93", с клавишей "Ctrl" - "103", а с клавишей "Alt" - "113".
Существуют так называемые "алфавитно-цифровые" ("белые") и "управляющие" ("серые") клавиши. Первые генерируют скен-код и ASCII символы. Вторые генерируют только расширенный скен-код, а в поле "ASCII символа" стоит ноль. Благодаря этому программист легко может понять, как обрабатывать код клавиши: выводить ли символ на экран или запускать управляющую последовательность действий.
Более подробно о скэн-кодах клавиш смотри [1, 8, 33].
5.1.2. "Эхопечать" символов
При вводе с клавиатуры пара значений "Скен-код" - "ASCII символ" заносится в клавиатурный буфер для её обработки на компьютере. При этом на старых терминалах все введённые символы отображались на экране дисплея. Но, с появлением персональных ЭВМ , выяснилось, что такой вывод ("Эхопечать") не всегда удобный. Что делать, если Вы вводите пароль, и Вы не хотите, чтобы кто-либо его прочитал с экрана? А что делать, если Вы используете алфавитно-цифровую клавишу как управляющую (например, при обработке меню)? В этом случае Вам помогут функции ввода с клавиатуры без эхопечати.
5.1.3. Клавиатурный буфер
Полученный в результате преобразований в контроллере двухбайтовый код посылается в кольцевой буфер ввода, который служит для синхронизации ввода данных с клавиатуры и приёма их выполняемой программой. Объём кольцевого буфера составляет 15 слов (30 байт). При этом буфер организован по принципу: "первым записан - первым считан" (английская аббревиатура "FIFO"). При переполнении буфера новые коды в него не поступают, а нажатие на клавиши вызывает предупреждающие сигналы.
5.2. Основные функции для ввода символов с клавиатуры
5.2.1. Консольный ввод в Ассемблере
5.2.1.1. Ожидание ввода символа без эхопечати
Функции 7 и 8 прерывания 21H ожидают ввода символа, если буфер клавиатуры пуст; появление символа на экране не отображается.
Разница между этими функциями в том, что функция 8 распознаёт специальное сочетание клавиш "Ctrl+Break", а функция 7 игнорирует это сочетание клавиш.
В обоих случаях функция возвращает символ в регистр AL. Если AL содержит ASCII 0, то получен расширенный код. Повторите вызов прерывания с теми же параметрами, и в AL появится второй байт расширенного кода.
5.2.1.2. Ожидание ввода символа с эхопечатью
При вводе символов с эхопечатью эхо вводимых символов выдаётся на экран. При этом символы "возврат каретки" и "забой" переводятся в соответствующие перемещения курсора, а не отображаются как ASCII символы. Вывод эха осуществляется с текущей позиции на экране. При этом курсор после вывода смещается на позицию вправо, а по достижении правой границы экрана - переносит вывод на новую строку.
Функция 1 прерывания 21H ожидает ввода символа с клавиатуры, если её буфер пуст, а затем выводит его на экран в текущую позицию курсора. Функция обрабатывает нажатие "Ctrl+Break". Введённый символ сохраняется в регистре AL. Если содержимое AL равно ASCII 0, то для получения расширенного кода повторите прерывание.
Пример использования этой функции аналогичен примеру 5.1.
Функция 1 прерывания 21H полностью игнорирует клавишу "Esc". Клавиши табуляции интерпретируются нормально. Клавиша "Backspace" сдвигает курсор на одну позицию влево, но не стирает символ в этой позиции. Клавиша "Enter" вызывает перемещение курсора на первую позицию строки (нет автоматического переноса на новую строку).
5.2.1.3. Получение строки символов
Большинство языков программирования предоставляют возможности для ввода строки символов. Они используют возможности ввода символов с эхопечатью, помещая автоматически введённые символы в буфер оперативной памяти. Конечно же, должна быть выделена память, достаточная для приёма символов строки, и должна записываться длина строки при вводе. Если этого не сделать, то произойдёт отказ системы типа "переполнения буфера", которым может воспользоваться злоумышленник.
Функция 0AH прерывания 21H позволяет вводить строку длиной до 254 символов, выдавая эхо на терминал. Эта функция продолжает ввод символов до тех пор, пока не нажата клавиша "возврат каретки" ( "Enter" ). DS:DX указывает на строку, куда помещаются вводимые символы. При вводе первый байт этой позиции должен содержать число байтов, отводимой для этой строки. После того, как строка введена, второй байт даёт число реально введённых символов. Сама строка начинается с третьего байта.
Надо отвести достаточно памяти для строки нужной длины, плюс 2 байта для дескриптора строки плюс 1 добавочный байт для символа "Возврат каретки". Код возврата каретки: ASCII 13, - вводится как последний символ строки, но не учитывается в результате, который функция помещает во второй байт дескриптора.
Таким образом, для получения 50 - символьной строки надо отвести минимум 53 байта памяти, и поместить в первый байт памяти строки число ASCII 51. После ввода 50 символов второй байт дескриптора будет содержать ASCII 50, а 53-й байт отведённой памяти будет содержать ASCII 13.
В этой процедуре можно использовать возможности редактирования строки MS-DOS. Нажатие "Backspace" или "стрелка влево" удаляет символ с экрана без помещения его в память. Работает клавиша табуляции, а расширенные коды игнорируются. Допускаются пустые строки (содержащие только символ ASCII 13). На дисплее при достижении правого края экрана вводимая строка переносится на следующую строку дисплея, а при достижении правого нижнего угла экран сдвигается на строку вверх. Если вводится больше символов, чем отведено для строки, лишние символы игнорируются, и включается гудок динамика.
В предыдущих лекциях мы познакомились с командами вывода на экран. Для этого мы использовали объект System.out , и его методы print() и println() . Просто и удобно.
Но, как вы уже наверное догадываетесь, одного вывода на экран недостаточно. Цель большинства программ — сделать что-то полезное для пользователя. Поэтому очень часто нужно, чтобы пользователь мог вводить данные с клавиатуры.
Как и для вывода, для ввода данных тоже есть специальный объект — System.in . Но, к сожалению для нас, он не настолько удобен, как нам бы хотелось. Этот объект позволяет считывать данные с клавиатуры по одному символу за раз.
Поэтому мы воспользуемся еще одним классом, который в паре с объектом System.in даст нам все, что нужно. В Java уже давно есть классы на все случаи жизни. С одним из них мы сейчас и познакомимся.
2. Класс Scanner
Считывание с клавиатуры с помощью объекта типа Scanner будет выглядеть примерно так:
Код | Пояснение |
---|---|
Создаем объект класса Scanner . Читаем с клавиатуры строку текста . Читаем с клавиатуры число . |
Выглядит вроде несложно, но так ли все просто на самом деле?
Думаю, у вас появилась куча вопросов, и сейчас мы на них ответим.
Но для начала продемонстрируем пример полной программы, где используется класс Scanner :
3. Создание объекта Scanner
Такая строка может сбивать с толку, однако вы будете постоянно встречать похожие вещи. Так что, думаем, настало время объяснить, что тут написано.
Вспомним, как мы обычно создаем переменную с текстом:
Сначала мы пишем тип переменной ( String ), затем ее имя ( str ) и, наконец, после знака равно пишем значение.
В нашей странной строке на самом деле все то же самое:
Объявление и инициализация переменной типа ScannerВсе, что находится слева от знака равно — это объявление переменной типа Scanner по имени console . Можно было назвать ее, например, s или scanner , или даже keyboard . Тогда код выглядел бы так:
Думаю, теперь все стало гораздо понятнее.
А код, что находится справа от знака равно , немного сложнее. Имеется в виду new Scanner(System.in); Но тут тоже ничего космического.
В этом коде мы говорим Java-машине: создай новый объект (слово new ) типа Scanner и передай в него в качестве параметра то, из чего новосозданный объект Scanner будет брать данные — объект System.in .
После выполнения всей этой строки у нас появится переменная по имени console типа Scanner , с помощью которой наша программа сможет считывать данные с клавиатуры.
4. Вызов методов
В приведенном выше примере наша переменная console типа Scanner хранила у себя внутри ссылку на объект типа Scanner .
Чтобы вызвать методы объекта, на который ссылается переменная, нужно после имени переменной написать точку, а затем имя метода и параметры. Общий вид этой команды такой:
Вызов метода объекта, на который ссылается переменнаяЕсли вы не планируете передавать в функцию параметры, нужно писать просто пустые скобки:
5. Ввод данных с консоли
Вводить данные с клавиатуры, когда у нас есть объект типа Scanner , очень легко.
Чтобы считать с клавиатуры строку , нужна команда:
Когда программа дойдет до выполнения этой строки, она приостановится и будет ждать, пока пользователь введет данные и нажмет клавишу enter. После этого все, что ввел пользователь, будет сохранено в переменную str .
Чтобы считать с клавиатуры число , нужна команда:
Тут все аналогично предыдущей команде. Когда программа дойдет до выполнения этой строки, она приостановится и будет ждать, пока пользователь введет данные и нажмет клавишу enter. После этого все, что ввел пользователь, будет преобразовано в число и сохранено в переменную number .
Если пользователь ввел данные, которые невозможно преобразовать в целое число, в программе возникнет ошибка, и она завершится.
Чтобы считать с клавиатуры дробное число , нужна команда:
Эта команда полностью аналогична команде nextInt() , только она проверяет, что введенные данные можно преобразовать в число double .
Пример программы, которая считывает с клавиатуры два числа и выводит их сумму:
Пользователь может ввести несколько чисел в одной строке, разделив их пробелами: такая ситуация будет корректно обработана методами класса Scanner . Однако числа будут считаны программой только после того, как пользователь нажмет Enter .
Считай с клавиатуры три строки. А затем: 1. Выведи на экран третью строку в неизменном виде. 2. Выведи на экран вторую строку, предварительно преобразовав ее к верхнему регистру. 3. Выведи на экран первую строку, предварительно преобразовав ее к нижнему регистру. Пример ввода: Строка Номер РАЗ Втор Считай с клавиатуры три целых числа. Выведи на экран их среднее арифметическое. Пример ввода: 50 101 201 Пример вывода: 117 Среднее арифметическое - это число, равное сумме всех чисел, деленной на их количество. Используй деление без остатка.6. Другие методы класса Scanner
Это, кстати, были не все методы класса Scanner . Полный список будет выглядеть примерно так:
Метод | Описание |
---|---|
Считывает данные и преобразует их в тип byte | |
Считывает данные и преобразует их в тип short | |
Считывает данные и преобразует их в тип int | |
Считывает данные и преобразует их в тип long | |
Считывает данные и преобразует их в тип float | |
Считывает данные и преобразует их в тип double | |
Считывает данные и преобразует их в тип boolean | |
Считывает одно «слово». Слова разделяются пробелами или enter | |
Считывает целую строку |
Есть еще методы, которые позволяют проверить тип еще не считанных данных (чтобы знать, каким методом их считывать).
Метод | Описание |
---|---|
Там тип byte ? Его можно будет преобразовать к byte ? | |
Там тип short ? Его можно будет преобразовать к short ? | |
Там тип int ? Его можно будет преобразовать к int ? | |
Там тип long ? Его можно будет преобразовать к long ? | |
Там тип float ? Его можно будет преобразовать к float ? | |
Там тип double ? Его можно будет преобразовать к double ? | |
Там тип boolean ? Его можно будет преобразовать к boolean ? | |
Там есть еще одно слово? | |
Там есть еще одна строка? |
7. Ввод данных из строки
Мы уже говорили выше, что класс Scanner умеет считывать данные из разных источников. И один из этих источников — строка текста .
Начинающему разработчику зачастую сложно разобраться в средствах ввода-вывода (I/O), поскольку присутствует небольшая путаница в определении различий этих способов. В данном материале попробуем заполнить этот пробел и разобраться в классификации основных типов ввода-вывода.
I/O в аппаратном обеспечении
В современных операционных системах средства ввода-вывода представляют собой способы взаимодействия между обработчиком информации и внешним миром. Сюда можно отнести чтение или запись файлов на жёсткий диск или SSD, отправку и получение данных по сети, отображение информации на мониторе и получение ввода с мыши и клавиатуры.
Способы взаимодействия современных ОС с периферийными устройствами зависят от типа устройства, возможностей прошивки и аппаратного обеспечения. Можно считать, что периферия может обрабатывать несколько запросов одновременно. То есть время последовательного взаимодействия прошло. В этом смысле все взаимодействия устройств ввода-вывода с процессором асинхронны и находятся на стороне аппаратного обеспечения.
Такой асинхронный механизм называется аппаратным прерыванием. В простом случае, процессор отправляет запрос к внешнему устройству и начинает бесконечный цикл, в котором он каждый раз запрашивает у периферии, готовы ли данные, которые процессор мог бы считать, и ждёт в цикле, пока периферия не выдаст ему эти данные. Этот метод ввода-вывода называется методом опроса поскольку процессор должен постоянно проверять состояние периферии.
3–5 декабря, Онлайн, Беcплатно
На самом деле, на современном оборудовании процессор просит периферию выполнить действие и забывает о нём, продолжая обрабатывать другие инструкции. Как только устройство завершит свою работу, оно сообщает об этом процессору, вызывая прерывание. Это происходит на уровне аппаратного обеспечения, и при этом процессору никогда не приходится ожидать или опрашивать периферию, что освобождает его для другой работы, пока периферия сама не сообщит о своей готовности.
I/O в программном обеспечении
В среде программного обеспечения существует большое количество видов ввода и вывода: блокирующий, неблокирующий, мультиплексированный и асинхронный. Давайте рассмотрим их по очереди.
Блокирующий метод
Помните, что любая пользовательская программа запускается внутри процесса, а код выполняется в контексте потока? Предположим, вы пишете программу, которой нужно читать информацию из файла. С блокирующим вводом-выводом вы просите ОС «усыпить» ваш поток и «разбудить» его только после того, как данные из файла будут доступны для чтения.
То есть блокирующий ввод-вывод называется так, потому что поток, который его использует, блокируется и переходит в режим ожидания, пока ввод-вывод не будет завершён.
Неблокирующий метод
Проблема метода блокировки заключается в том, что поток будет спать, пока ввод-вывод не завершится. Поток не сможет выполнять никаких других задач, кроме ожидания завершения ввода-вывода. Иногда вашей программе больше и не надо ничего делать. В противном случае во время ожидания ввода-вывода было бы полезно выполнять другие задачи.
Мультеплексированный метод
Проблема с неблокирующим вводом-выводом в том, что с ним не удобно работать, если задачи, которые выполняет программа, ожидая ввода-вывода, сами из себя представляют другой ввод-вывод.
Хорошо, если ПО просит ОС прочитать содержимое из файла А, после чего выполняет какие-нибудь сложные вычисления. Затем проверяет, завершилось ли чтение файла А, и если да, то просто продолжает ту работу, для которой нужно было содержимое файла, а иначе снова выполняет некоторое количество сложных вычислений и так далее.
Но что, если программе не нужно выполнять сложные вычисления? Ей просто нужно прочесть файл A и одновременно файл B. Пока ПО ожидает завершения обработки файла А, оно делает неблокирующий вызов чтения содержимого файла В. Во время ожидания обработки программе больше нечего делать, потому она входит в бесконечный цикл опроса, проверяя, готово ли A и готово ли B, снова и снова. Это либо нагрузит процессор проверками состояния ваших неблокирующих вызовов, либо вам придётся вручную добавить какое-то произвольное время, которое ваш поток будет «спать», а значит, программа немного позже заметит, что ввод-вывод готов, что отрицательно скажется на пропускной способности ПО.
Во избежание этого можно использовать мультиплексированный ввод-вывод. Он тоже блокирует поток на операциях ввода-вывода, но вместо того, чтобы производить блокировку по очереди, вы можете запланировать все операции ввода-вывода, которые вам нужно сделать, и блокировать их все. Операционная система разбудит поток, когда какая-нибудь из операций завершится. В некоторых реализациях мультиплексированного ввода-вывода можно даже точно указать, что вы хотите, чтобы поток разбудили, только когда заданный набор операций ввода-вывода будет завершён, например, когда файлы A и C, или файлы B и D будут готовы.
Таким образом ПО делает неблокирующий вызов чтения файла A, потом неблокирующий вызов чтения файла B, и наконец говорит ОС: усыпи мой поток, и разбуди его, когда A и B будут оба готовы, или когда один из них будет готов.
Асинхронный метод
Проблема мультиплексированного ввода-вывода в том, что поток всё-таки спит, пока ввод-вывод не будет готов для обработки. Для многих программ это подходит, поскольку у них нет других задач, пока они ждут завершения операций ввода-вывода. Но иногда у них есть и другие задачи.
Например, ПО вычисляет цифры числа π и одновременно суммирует значения из нескольких файлов. Вам хотелось бы запланировать все операции чтения файлов, пока программа ждёт их выполнения, вычислять цифры числа π. Когда какой-нибудь из файлов будет прочитан, ПО прибавит записанное в нём значение и продолжит вычислять цифры числа π дальше, пока ещё один файл не будет прочитан.
Чтобы это работало, нужно, чтобы ваше вычисление цифр числа π могло быть прервано вводом-выводом, когда он завершается. Это можно сделать с помощью обратных вызовов, связанных с событиями. Вызов на чтение принимает функцию обратного вызова и возвращается немедленно. Когда ввод-вывод завершается, операционная система остановит ваш поток и выполнит обратный вызов. Когда обратный вызов завершится, система возобновит работу вашего потока.
Многопоточность или однопоточность?
Вы, наверно, заметили, что все вышеописанные способы ввода-вывода работают в рамках одного потока, главного потока вашего приложения. На самом деле, для выполнения ввода-вывода не требуется отдельный поток, поскольку, как вы видели в начале статьи, вся периферия выполняет ввод-вывод асинхронно. Поэтому и возможно делать блокирующий, неблокирующий, мультиплексированный и асинхронный ввод-вывод в однопоточной модели и одновременный ввод-вывод может работать без поддержки многопоточности.
Но обработка результатов операций ввода-вывода может быть и многопоточной. Это позволяет программе делать одновременные вычисления поверх одновременного ввода-вывода. Так что, ничто не мешает вам совмещать многопоточность и эти механизмы ввода-вывода.
В самом деле, есть пятый популярный метод ввода-вывода, который требует многопоточности. Его часто путают с неблокирующим или асинхронным, поскольку он похож по интерфейсу на те два. Он работает просто: он использует блокирующий ввод-вывод, но каждый блокирующий вызов делается в отдельном потоке. В зависимости от реализации, вызов либо принимает функцию обратного вызова, либо использует модель опроса, как если он возвращает Future .
Читайте также: