ByteBuffer在Java中有什么用?[关闭]


199

ByteBufferJava 中的示例应用程序是什么?请列出使用此示例的任何示例方案。谢谢!


1
Apache Hadoop的压缩(例如zlib编解码器)使用jave.nio中的ByteBuffer。
尼克,

非常适合将数据发送到GPU。
像素

Answers:


138

是对它的用途和缺点的很好的描述。本质上,只要需要执行快速的低级I / O,就可以使用它。如果要实现TCP / IP协议,或者正在编写数据库(DBMS),则该类将派上用场。


3
在使用Java和Cassandra DB开发的高流量网站中,它是否有用?
阿克林2011年

1
快速搜索后,似乎是,Cassandra确实使用了ByteBuffer:mail-archive.com/commits@cassandra.apache.org/msg14967.html 如果您想知道一个原始网站,可能会有,但通常它只是将被网站间接使用-通过使用诸如cassandra之类的工具
kelloti 2011年

1
不错的链接,谢谢。想补充这一块,我发现有用- worldmodscode.wordpress.com/2012/12/14/...
彼得Perháč

错误的链接,我担心...
RoyalBigMack

96

ByteBuffer类很重要,因为它构成了Java中使用通道的基础。ByteBuffer类定义了对字节缓冲区的六类操作,如Java 7文档中所述

  • 读取和写入单个字节的绝对和相对的getput方法;

  • 相对批量获取方法,用于将字节的连续字节序列从此缓冲区传输到数组中;

  • 相对批量放置方法,用于将字节数组或某个其他字节缓冲区中连续的字节序列传输到此缓冲区中;

  • 绝对和相对的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

56
此注释的大部分内容是从java 7文档中复制的。
Janus Troelsen 2013年

6
除非您利用非显而易见的副作用,否则我相信您可能会使用错误的方法进行绝对认沽。Javadoc似乎指示绝对放置需要索引值。
Chuck Wolber

6
即使它只是api文档的副本,它的分数甚至不及bcs,有些人似乎也懒得看它。
克里斯

1
在这些示例之一中有一个错误。“绝对看跌期权”缺少表示索引的第一个参数(在这种情况下为0)。
bvdb 2015年

21

使用面向流的API的Java IO使用缓冲区作为用户空间内数据的临时存储来执行。通过DMA从磁盘读取的数据首先复制到内核空间的缓冲区中,然后再传输到用户空间的缓冲区中。因此存在开销。避免使用它可以显着提高性能。

如果有一种方法可以直接访问内核空间中的缓冲区,则可以跳过用户空间中的该临时缓冲区。Java NIO提供了一种方法。

ByteBuffer是Java NIO提供的几个缓冲区之一。它只是一个用于读取数据或向其中写入数据的容器或容纳槽。通过allocateDirect()在Buffer上使用API 分配直接缓冲区来实现上述行为。

字节缓冲区的Java文档包含有用的信息。


14

在Android中,您可以在C ++和Java之间创建共享缓冲区(使用directAlloc方法)并在两侧进行操作。


13

是一篇很棒的文章,解释了ByteBuffer的好处。以下是本文的重点:

  • 无论是直接缓冲区还是间接缓冲区,ByteBuffer的第一个优点是对结构化二进制数据(例如,答案之一所述的低级IO )进行有效的随机访问。在Java 1.4之前,要读取此类数据,可以使用DataInputStream,但不能进行随机访问。

以下是专门针对直接ByteBuffer / MappedByteBuffer的好处。请注意,直接缓冲区是在堆外部创建的:

  1. 不受gc周期的影响:直接缓冲区在垃圾回收周期中不会移动,因为它们位于堆外部。TerraCota的BigMemory缓存技术似乎在很大程度上依赖于此优势。如果它们在堆上,则会降低gc暂停时间。

  2. 性能提升:在流IO中,读取调用将需要系统调用,这需要在用户模式与内核模式之间进行上下文切换,反之亦然,这将是昂贵的,尤其是在不断访问文件的情况下。但是,使用内存映射可以减少上下文切换,因为更可能在内存中找到数据(MappedByteBuffer)。如果内存中有可用数据,则无需调用操作系统即可直接访问数据,即无需上下文切换。

请注意,MappedByteBuffers非常有用,尤其是在文件较大且很少访问几组块的情况下。

  1. 页面共享:内存映射文件可以在进程之间共享,因为它们是在进程的虚拟内存空间中分配的,并且可以在进程之间共享。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.