Что такое использование ByteBuffer в Java?

Каковы примеры приложений для ByteBuffer в Java? Пожалуйста, перечислите любые примеры сценариев, в которых это используется. Спасибо!

Ответ 1

Это является хорошим описанием его использования и недостатков. Вы по существу используете его, когда вам нужно выполнять быстрый ввод/вывод низкого уровня. Если вы собираетесь реализовать протокол TCP/IP или если вы пишете базу данных (СУБД), этот класс пригодится.

Ответ 2

Класс ByteBuffer важен, поскольку он создает основу для использования каналов в Java. Класс ByteBuffer определяет шесть категорий операций над байтовыми буферами:

  • Абсолютный и относительный get и put, которые читают и записывают одиночные байты;

  • Относительные bulk get методы, которые передают непрерывные последовательности байтов из этого буфера в массив;

  • Относительные bulk put методы, которые переносят непрерывные последовательности байтов из байтового массива или какого-либо другого байтового буфера в этот буфер;

  • Абсолютные и относительные методы get и put, которые читают и записывают значения других примитивных типов, переводя их в последовательности байтов и из них в конкретном порядке байтов;

  • Способы создания буферов просмотра, которые позволяют просматривать байтовый буфер как буфер, содержащий значения некоторого другого примитивного типа; и

  • Способы уплотнение, дублирование, и срезание байтового буфера.

Example code : Putting Bytes into a buffer.

    // Create an empty ByteBuffer with a 10 byte capacity
    ByteBuffer bbuf = ByteBuffer.allocate(10);

    // Get the buffer capacity
    int capacity = bbuf.capacity(); // 10

    // Use the absolute put(int, byte).
    // This method does not affect the position.
    bbuf.put(0, (byte)0xFF); // position=0

    // Set the position
    bbuf.position(5);

    // Use the relative put(byte)
    bbuf.put((byte)0xFF);

    // Get the new position
    int pos = bbuf.position(); // 6

    // Get remaining byte count
    int rem = bbuf.remaining(); // 4

    // Set the limit
    bbuf.limit(7); // remaining=1

    // This convenience method sets the position to 0
    bbuf.rewind(); // remaining=7

Ответ 3

В Android вы можете создать общий буфер между С++ и Java (с помощью метода directAlloc) и управлять им с обеих сторон.

Ответ 4

JAVA IO с использованием ориентированных на поток API-интерфейсов выполняется с использованием буфера в качестве временного хранения данных в пользовательском пространстве. Данные, считываемые с диска DMA, сначала копируются в буферы в пространстве ядра, а затем переносятся в буфер в пространстве пользователя. Следовательно, есть накладные расходы. Избежание этого может значительно повысить производительность.

Мы могли бы пропустить этот временный буфер в пользовательском пространстве, если бы был прямой доступ к буферу в пространстве ядра. JAVA NIO предоставляет способ сделать это.

ByteBuffer входит в число нескольких буферов, предоставляемых JAVA NIO. Его просто контейнер или резервуар для чтения данных или записи данных. Вышеизложенное поведение достигается путем выделения прямого буфера с использованием allocateDirect() API в буфере.

Java-документация байтового буфера имеет полезную информацию.

Ответ 5

Здесь - отличная статья, объясняющая преимущества ByteBuffer. Ниже приведены основные положения статьи:

  • Первое преимущество ByteBuffer независимо от того, является ли оно прямым или косвенным эффективным случайным доступом структурированных двоичных данных (например, низкоуровневый IO, как указано в одном из ответов). До Java 1.4 для чтения таких данных можно использовать DataInputStream, но без произвольного доступа.

Ниже приведены преимущества для прямого ByteBuffer/MappedByteBuffer. Обратите внимание: прямые буферы создаются вне кучи:

  • Не затрагивается циклами gc. Прямые буферы не будут перемещаться во время циклов сбора мусора, поскольку они находятся вне кучи. TerraCota BigMemory Технология кэширования, похоже, сильно зависит от этого преимущества. Если бы они были в куче, это замедляло бы время паузы gc.

  • Повышение производительности. В потоковом IO чтение вызовов будет связано с системными вызовами, для которых требуется контекстный переключатель между пользователем в режим ядра и наоборот, что было бы дорогостоящим, особенно если файл доступ к ним постоянно. Однако при сопоставлении памяти это контекстное переключение сокращается, так как данные, скорее всего, будут найдены в памяти (MappedByteBuffer). Если данные доступны в памяти, к ним обращаются напрямую без вызова ОС, то есть без контекстного переключения.

Обратите внимание, что MappedByteBuffers очень полезны, особенно если файлы большие, и несколько групп блоков получают доступ чаще.

  1. Обмен страницами. Файлы с отображением памяти могут совместно использоваться между процессами, поскольку они распределены в пространстве виртуальной памяти процесса и могут совместно использоваться всеми процессами.