Какая польза от ByteBuffer в Java? [закрыто]

199

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

Aklin
источник
1
Сжатие Apache Hadoop (например, кодек zlib) использует ByteBuffer из jave.nio.
Никк
Хорошо для отправки данных в графические процессоры.
Pixel

Ответы:

138

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

kelloti
источник
3
Полезно ли это для сайта с высоким трафиком, разработанного с использованием Java & Cassandra DB?
Аклин
1
После быстрого поиска выясняется, что да, Cassandra действительно использует ByteBuffer: mail-archive.com/commits@cassandra.apache.org/msg14967.html Если вас интересует необработанный веб-сайт, он может быть, но обычно это только будет использоваться сайтами косвенно - с помощью таких инструментов, как
cassandra
1
неплохая ссылка, спасибо. Я хотел бы добавить этот, который я нашел полезным - worldmodscode.wordpress.com/2012/12/14/…
Петер Перхач
Плохая ссылка, я боюсь ...
RoyalBigMack
96

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

  • Абсолютные и относительные методы get и 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's 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
ykombinator
источник
56
большая часть этого комментария скопирована из документации Java 7 .
Янус Троелсен
6
Если вы не пользуетесь неочевидным побочным эффектом, я полагаю, что вы используете неправильный метод для абсолютного пута. Javadoc, кажется, указывает, что для абсолютного пут требуется значение индекса.
Чак Вольбер,
6
даже если это просто копия api doc, даже если его оценка bcs, некоторые люди кажутся слишком ленивыми, чтобы взглянуть на него.
Крис
1
В одном из примеров есть ошибка. «Абсолютная позиция» пропускает первый параметр, который представляет индекс (0 в данном случае).
bvdb
21

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

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

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

Документация по Java для Byte Buffer содержит полезную информацию.

deepujain
источник
14

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

someUser
источник
13

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

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

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

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

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

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

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