在Java中使用ByteBuffer有什么用?

Akl*_*lin 184 java buffer bytebuffer

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

kel*_*oti 129

是对其用途和缺点的良好描述.无论何时需要执行快速低级I/O,您基本上都可以使用它.如果您要实现TCP/IP协议,或者如果您正在编写数据库(DBMS),则此类将派上用场.

  • 在使用Java和Cassandra DB开发的高流量网站中它是否有用? (3认同)
  • 不错的链接,谢谢。想添加这个我发现有用的 - https://worldmodscode.wordpress.com/2012/12/14/the-java-bytebuffer-a-crash-course/ (2认同)

yko*_*tor 92

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
Run Code Online (Sandbox Code Playgroud)

  • 此评论的大部分内容都是从[java 7 docs](http://docs.oracle.com/javase/7/docs/api/java/nio/ByteBuffer.html)中复制而来的. (55认同)
  • 除非你利用一个非明显的副作用,我相信你可能会使用错误的方法进行绝对放置.Javadoc似乎表明绝对put需要一个索引值. (6认同)
  • 即使它只是api doc的一个副本,它甚至可以解决它的分数bcs,有些人似乎太懒了看看它. (6认同)

dee*_*ain 20

使用面向流的API的Java IO使用缓冲区作为用户空间内的数据的临时存储来执行.通过DMA从磁盘读取的数据首先被复制到内核空间中的缓冲区,然后传输到用户空间中的缓冲区.因此有开销.避免它可以获得相当大的性能提升.

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

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

Byte Buffer的Java文档包含有用的信息.


som*_*ser 13

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


Dhe*_*uru 13

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

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

以下是直接ByteBuffer/MappedByteBuffer的优点.请注意,直接缓冲区是在堆外部创建的:

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

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

请注意,MappedByteBuffers非常有用,特别是如果文件很大并且更频繁地访问几组块.

  1. 页面共享:内存映射文件可以在进程之间共享,因为它们在进程的虚拟内存空间中分配,并且可以跨进程共享.