Главная
Блог разработчиков phpBB
 
+ 17 предустановленных модов
+ SEO-оптимизация форума
+ авторизация через соц. сети
+ защита от спама

Разбираемся с java.nio.*

Anna | 5.06.2014 | нет комментариев

Этот пакет был добавлен еще в Java 1.4, впрочем многие разработчики о нем либо не знают, либо не умеют пользоваться. В сети немного материалов на эту тему, исключительно на русском.

Вступление

Java New IO — «новая» реализация IO. Ее призвание — решить задачи продуктивности стандартного блокирующего IO. Примерно все способы чтения-записи без блокировок, они читают либо записывают лишь теснее доступную информацию. Это разрешает в одном либо нескольких потоках обрабатывать всякое число подключений.

Продолжение под програкатом

Buffers

Больше функциональная и комфортная замена массивов. Применяется для хранения считанной информации и в качестве источника для записи. Каждого есть несколько типов буферов:

  • ByteBuffer — хранит байты. Может быть представлен в виде других буферов.
  • ShortBuffer — хранит short‘ы. Может быть представлен в виде ByteBuffer‘а
  • IntBuffer — хранит int‘ы. Может быть представлен в виде ByteBuffer‘а
  • LongBuffer — хранит long‘и. Может быть представлен в виде ByteBuffer‘а
  • FloatBuffer — хранит float‘ы. Может быть представлен в виде ByteBuffer‘а
  • CharBuffer — хранит char‘ы. Может быть представлен в виде ByteBuffer‘а

Помимо этого, дозволено сделать ReadOnlyBuffer способом asReadOnly(); Всякий буфер имеет размер (capacity), лимит (limit), нынешнюю позицию (position) и метку (mark):

  • размер — сколько данных в себя физически может вместить буфер. Устанавливается при создании
  • лимит — до какой позиции дозволено читать либо записывать данные в буфер. Дозволено установить вручную
  • позиция — сколько байт теснее записано/прочитано. Дозволено установить вручную, по умолчанию равен нулю
  • метка — сохраненная позиция, разрешает возвратиться к необходимому месту в буфере

Помимо этого, у всякого буфера есть пара способов, которые разрешают им руководить:

  • get(index) — возвращает элемент на указанной позиции
  • put(index, type) — устанавливает элемент на указанную позицию
  • get() — возвращает элемент на нынешней позиции, после этого повышает позицию на 1
  • put(type) — устанавливает элемент type на нынешнюю позицию, после этого повышает позицию на 1
  • clear() — ставит позицию на 0, лимит на размер и удаляет метку. Подготавливает буфер для записи
  • flip() — ставит лимит равным позиции, после этого позицию на 0 и удаляет метку. Подготавливает буфер для чтения
  • rewind() — ставит позицию на 0 и удаляет метку. Применяется для того Дабы снова прочесть буфер
  • position(int), position() — установка и приобретение позиции соответственно
  • limit(int), limit() — установка и приобретение лимита соответственно
  • remaing() — возвращает сколько еще элементов дозволено прочитать либо записать
  • mark() — устанавливает метку на нынешнюю позицию
  • reset() — возвращает позицию к метке

Сделать буфер дозволено тоже различным методами:

  • (Type)Buffer.allocate(capacity) — создает буфер в Heap. Дозволено преобразовать в массив с поддержкой способа array()
  • ByteBuffer.allocateDirect(capacity*typesize).asType() — создает буфер в системной памяти. Невозможно преобразовать в массив.

Channels

Заместо Stream’ов, в NIO применяются каналы (Channel), которые могут объеденять функциональность InputStream и OutputStream.
Сам по себе Channel имеет только способы close() и isOpen(). Остальные способы добавляются реализуемыми им интерфейсами:

  • ReadableChannel — вероятность чтения содержимого из канала в ByteBuffer (channel.read(dst))
  • WriteableChannel — вероятность записи содержимого в канал из ByteBuffer (channel.write(src))
  • SelectableChannel — вероятность применять Selector и отключить блокировки (об этом ниже)
  • AsynchronousChannel — вероятность читать и записывать из нескольких потоков

Для комфортного управления SelectableChannel есть особый класс — Selector. Его дозволено применять только позже того, как Вы отключили блокировки (channel.configureBlocking(false));

Selectors и SelectionKeys

Selector — неповторимый слушатель, тот, что уведомляет, когда с каналом дозволено совершить какое-то действие. Без него не получится сделать типичное NIO приложение. Для начала его нужно сделать. Selectorсоздается с статического способа Selector.open(). Позже создания селектора, нужно его зарегестрировать на надобном канале. Это делается с поддержкой способа:

SelectionKey key = channel.register(selector, ops, [attach])

Selection Op определяет, какие события нужно отслеживать:

  • SelectionKey.OP_READ — если в канале есть данные, доступные для чтения
  • SelectionKey.OP_WRITE — если канал доступен для записи.
    Внимание! Ставьте данный op только если есть данные, доступные для записи.
  • SelectionKey.OP_ACCEPT — только для ServerSocketChannel. Если есть непринятые подключения
  • SelectionKey.OP_CONNECT — только для *SocketChannel. Если подключение удачно закончилось

OP’ы дозволено объеденять с поддержкой логичного ЛИБО:

int ops = SelectionKey.OP_ACCEPT | SelectionKey.OP_READ;

SelectionKey — объект, тот, что провоцирует событие. Имеет несколько пригодных способов:

  • attach(Object) — добавляет «присоединение» к ключу. Скажем, обработчик
  • attachment() — возвращает ранее добавленное присоединение
  • channel() — возвращает канал, к которому прикреплен ключ
  • cancel() — убирает ключ из селектора

Дабы обрабатывать каналы с Selector‘ом, нужно сделать цикл, тот, что работает до закрытия канала. Пример приведени ниже:

while(!serverKey.isCancelled())
{
	selector.select(); // Ожидаем до того, как появится правда бы одно событие. Как появятся, выбираем ключи с этими событиями
	Iterator<SelectionKey> iterator = selector.selectedKeys().iterator(); // Получаем итератор выбранных ключей
	while(iterator.hasNext())
	{
		SelectionKey key = iterator.next();
		SelectableChannel channel = key.channel();
		if(key.isAcceptable())
		{
			// принимаем подключение у сервера. Здесь же его регистрируем в селекторе с OP_READ.
		}
		if(key.isReadable())
		{
			// читаем данные, если длина -1, удаляем ключ с поддержкой key.cancel();
		}
		if(key.isWriteable())
		{
			// записываем данные
		}
		iterator.remove(); // Удаляем ключ из выбранных, так как мы его обработали
	}
}
selector.close();

Это все, что необходимо знать для начала работы с NIO. Вопросы задавайте в комментариях.

Источник: programmingmaster.ru

Оставить комментарий
Форум phpBB, русская поддержка форума phpBB
Рейтинг@Mail.ru 2008 - 2017 © BB3x.ru - русская поддержка форума phpBB