在Java中使用ByteBuffer有什么用?

时间:2011-01-30 05:26:42

标签: java buffer bytebuffer

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

5 个答案:

答案 0 :(得分:117)

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

答案 1 :(得分:87)

ByteBuffer类很重要,因为它构成了在Java中使用通道的基础。 ByteBuffer 类在字节缓冲区as stated in the Java 7 documentation上定义了六类操作:

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

  •   
  • 将相邻的字节序列从此缓冲区转移到数组中的相对bulk get方法;

  •   
  • 将字节数组或其他字节缓冲区中的连续字节序列传输到此缓冲区的相对bulk put方法;

  •   
  • 绝对和相对的get和put方法,用于读取和写入其他原始类型的值,将它们转换为序列和   特定字节顺序的字节;

  •   
  • 创建视图缓冲区的方法,允许将字节缓冲区视为包含某些其他基本类型值的缓冲区;以及

  •   
  • compactingduplicatingslicing字节缓冲区的方法。

  •   

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

答案 2 :(得分:19)

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

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

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

Java Documentation of Byte Buffer has useful information.

答案 3 :(得分:13)

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

答案 4 :(得分:11)

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

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

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

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

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

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

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