Неблокирующий ввод-вывод (Java)
java.nio (NIO означает «Новый ввод/вывод»). [1] [2] ) — это набор языка программирования Java API-интерфейсов , которые предлагают функции для интенсивных операций ввода-вывода . Он был представлен J2SE в выпуске Java Sun Microsystems 1.4 в дополнение к существующему стандарту ввода-вывода. NIO был разработан в рамках процесса сообщества Java как JSR 51. [3] Расширение NIO, предлагающее новый API файловой системы под названием NIO.2, было выпущено вместе с Java SE 7 («Dolphin»). [4]
Особенности и организация
[ редактировать ]API-интерфейсы NIO были разработаны для обеспечения доступа к низкоуровневым операциям ввода-вывода современных операционных систем. Хотя API-интерфейсы сами по себе являются относительно высокоуровневыми, их цель состоит в том, чтобы облегчить реализацию, которая может напрямую использовать наиболее эффективные операции базовой платформы.
API-интерфейсы Java NIO представлены в java.nio
пакет и его подпакеты. В документации Oracle указаны эти функции.
- Буферы для данных примитивных типов
- наборов символов Кодеры и декодеры
- Средство сопоставления с образцом, основанное на Perl (в пакете регулярных выражениях в стиле
java.util.regex
) - Каналы, новая примитивная абстракция ввода-вывода.
- Файловый интерфейс, поддерживающий блокировки и сопоставление памяти файлов размером до
Integer.MAX_VALUE
байты (2 ГиБ ) - Мультиплексный для неблокирующий ввод-вывод написания масштабируемых серверов.
NIO-буферы
[ редактировать ]Передача данных NIO основана на буферах ( java.nio.Buffer
и родственные классы). Эти классы представляют собой непрерывный объем памяти вместе с небольшим количеством операций передачи данных. Хотя теоретически это структуры данных общего назначения, реализация может выбирать память для характеристик выравнивания или подкачки, которые иначе недоступны в Java. Обычно это используется для того, чтобы позволить содержимому буфера занимать ту же физическую память, которая используется базовой операционной системой для ее собственных операций ввода-вывода, что обеспечивает наиболее прямой механизм передачи и устраняет необходимость в любом дополнительном копировании. В большинстве операционных систем, при условии, что конкретная область памяти имеет правильные свойства, передача может происходить вообще без использования ЦП. Буфер NIO намеренно ограничен в возможностях для достижения этих целей.
Существуют буферные классы для всех примитивных типов Java, кроме boolean
, который может использовать память совместно с байтовыми буферами и допускать произвольную интерпретацию базовых байтов.
Использование
[ редактировать ]Буферы NIO поддерживают несколько указателей, определяющих функции их методов доступа. Реализация буфера NIO содержит богатый набор методов для изменения этих указателей:
- The
flip()
Вместо выполнения функции «переворота» или пейджинга в каноническом смысле перемещает указатель позиции в начало координат базового массива (если таковой имеется), а указатель предела — в предыдущую позицию указателя позиции . - Три
get()
предоставляются методы для передачи данных из буфера NIO. Массовая реализация вместо выполнения «получения» в традиционном смысле слова «помещает» данные в указанный массив. Аргумент «смещение», передаваемый этому методу, относится не к смещению внутри буфера, из которого выполняется чтение, и не к смещению от указателя позиции , а скорее к смещению от 0 внутри целевого массива. - Если не использовать абсолютный
get()
иput()
методы, любыеget()
илиput()
осуществляется от указателя положения . Если нужно прочитать из другой позиции в базовом массиве, не меняя при этом позицию записи ,mark()
иreset()
методы были предоставлены. - The
mark()
Метод эффективно сохраняет положение указателя позиции , устанавливая указатель метки в положение указателя позиции .reset()
метод заставляет указатель положения перемещаться в метки . положение указателя - При вызове
clear()
метод илиflip()
метод, указатель метки отбрасывается. - The
clear()
Метод не обеспечивает обнуление буфера, но возвращает указатель предела на верхнюю границу базового массива, а указатель позиции — на ноль. put()
иget()
операции для буферов NIO не являются потокобезопасными.- Вы можете только
map()
аjava.nio.MappedByteBuffer
изjava.nio.channels.FileChannel
доInteger.MAX_VALUE
по размеру (2ГиБ); к регионам, выходящим за пределы этого предела, можно получить доступ, используя смещение больше нуля.
Каналы
[ редактировать ]Каналы ( классы, реализующие интерфейс java.nio.channels.Channel
) предназначены для обеспечения массовой передачи данных в буферы NIO и обратно. Это механизм передачи данных низкого уровня, существующий параллельно с классами библиотеки ввода-вывода более высокого уровня (пакеты java.io
и java.net
). Реализация канала может быть получена из класса передачи данных высокого уровня, такого как java.io.File
, java.net.ServerSocket
, или java.net.Socket
, и наоборот. Каналы аналогичны « файловым дескрипторам », встречающимся в Unix-подобных операционных системах.
Файловые каналы ( java.nio.channels.FileChannel
) может использовать произвольные буферы, но также может создать буфер, напрямую сопоставленный с содержимым файла с помощью файла, отображенного в памяти . Они также могут взаимодействовать с блокировками файловой системы . Аналогично, сокетов ( каналы java.nio.channels.SocketChannel
и java.nio.channels.ServerSocketChannel
) позволяют передавать данные между сокетами и буферами NIO.
FileChannel
может использоваться для копирования файла, что потенциально гораздо более эффективно, чем использование старого чтения/записи с массивом байтов. Типичный код для этого:
// Getting file channels
try(FileChannel in = FileChannel.open(source, StandardOpenOption.READ);
FileChannel out = FileChannel.open(target, StandardOpenOption.WRITE)) {
// JavaVM does its best to do this as native I/O operations.
in.transferTo(0, in.size(), out);
}
Селекторы
[ редактировать ]Селектор ( java.nio.channels.Selector
и подклассы) предоставляет механизм ожидания каналов и распознавания, когда один или несколько каналов становятся доступными для передачи данных. Когда в селекторе зарегистрировано несколько каналов, это позволяет блокировать ход программы до тех пор, пока хотя бы один канал не будет готов к использованию или пока не возникнет состояние прерывания.
Хотя такое поведение мультиплексирования можно реализовать с помощью потоков, селектор может обеспечить значительно более эффективную реализацию с использованием конструкций операционной системы более низкого уровня. концепций — select ( Например, POSIX-совместимая операционная система будет иметь прямое представление этих ) . Заметным применением этой конструкции могла бы стать общая парадигма серверного программного обеспечения, которая предполагает одновременное ожидание ответов в нескольких сеансах.
Наборы символов
[ редактировать ]В Java набор символов — это отображение между символами Юникода (или их подмножеством) и байтами.
java.nio.charset
Пакет NIO предоставляет средства для идентификации наборов символов и предоставления алгоритмов кодирования и декодирования для новых сопоставлений.
Прием
[ редактировать ]Неожиданно, что канал, связанный с файлом Java IO RandomAccess, закрывает дескриптор файла при прерывании, тогда как собственный метод чтения RandomAccessFiles этого не делает. [5]
JDK 7 и НИО.2
[ редактировать ]
![]() | Этот раздел нуждается в расширении . Вы можете помочь, добавив к нему . ( декабрь 2009 г. ) |
JDK 7 включает в себя java.nio.file
пакет, который вместе с Path
Класс (также новый в JDK 7), помимо других функций, предоставляет расширенные возможности для задач файловой системы, например, может работать с символическими / жесткими ссылками и выгружать большие списки каталогов в буферы быстрее, чем старый класс File.
java.nio.file
пакет и связанный с ним пакет, java.nio.file.attribute
, обеспечивают комплексную поддержку файлового ввода-вывода и доступа к файловой системе. Поставщик файловой системы zip также доступен в JDK 7.
The java.nio.file.LinkOption
— это пример эмуляции расширяемых перечислений с помощью интерфейсов. [6] В Java невозможно иметь один Enum
продлить еще один Enum
. Однако можно эмулировать расширяемый Enum
печатать, имея Enum
реализовать один или несколько интерфейсов. LinkOption
— это тип перечисления, который реализует как OpenOption
и CopyOption
интерфейсы, которые имитируют эффекты расширяемого Enum
тип. Небольшим недостатком этого подхода является то, что реализации не могут наследоваться между различными Enum
типы.
Цитаты
[ редактировать ]- ^ «Java NIO — Руководство разработчика основных библиотек Java» . doc.oracle.com . Проверено 30 сентября 2022 г.
- ^ «Начало работы с новым вводом-выводом (NIO)» . разработчик.ibm.com . Проверено 30 сентября 2022 г.
- ^ «JSR 51: Новые API ввода-вывода для платформы JavaTM» . Программа Java Community Process (SM) — JSR: запросы спецификаций Java . Проверено 23 мая 2009 г.
- ^ «Этот JSR будет поставляться как часть Java SE 7 «Dolphin».» «JSR 203: новые API ввода-вывода для платформы JavaTM («NIO.2»)» . Программа Java Community Process (SM) — JSR: запросы спецификаций Java . 30 января 2006 г. Проверено 23 мая 2009 г.
- ^ Не думайте, что вы знаете, что лучше , Шон Пирс, автор книги Gerrit (Программное обеспечение) , 14 мая 2010 г.
- ^ Перейти обратно: а б Bloch 2018 , стр. 176–179, Глава §6, пункт 38. Эмуляция расширяемых перечислений с помощью интерфейсов.
Ссылки
[ редактировать ]- Блох, Джошуа (2018). «Эффективная Java: Руководство по языку программирования» (третье изд.). Аддисон-Уэсли. ISBN 978-0134685991 .
Внешние ссылки
[ редактировать ]- Java SE 19 API Javaдокументация
- JDK 5.0 Новые API-интерфейсы ввода-вывода и руководства для разработчиков — описание нового ввода-вывода от Oracle Corporation
- Изучите Java SE 7 | Особенности НИО 2
- JSR 51 (НИО)
- JSR 203 (НИО.2)
- Архитектура высокомасштабируемого сервера на базе NIO — обсуждение Java NIO и шаблонов использования
- Учебное пособие по Java NIO
- Учебное пособие Rox по Java NIO
- Масштабируемый ввод-вывод в Java (PDF)