Java中ByteBuffer的示例应用程序是什么?请列出任何使用这种方法的示例场景。
ByteBuffer类很重要,因为它构成了在Java中使用通道的基础。ByteBuffer类定义了六类对字节缓冲区的操作,如Java 7文档中所述:
Absolute and relative get and put methods that read and write single bytes; Relative bulk get methods that transfer contiguous sequences of bytes from this buffer into an array; Relative bulk put methods that transfer contiguous sequences of bytes from a byte array or some other byte buffer into this buffer; Absolute and relative get and put methods that read and write values of other primitive types, translating them to and from sequences of bytes in a particular byte order; Methods for creating view buffers, which allow a byte buffer to be viewed as a buffer containing values of some other primitive type; and Methods for compacting, duplicating, and slicing a byte 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
使用面向流的api的Java IO使用缓冲区作为用户空间内数据的临时存储来执行。通过DMA从磁盘读取的数据首先复制到内核空间的缓冲区,然后再传输到用户空间的缓冲区。因此有开销。避免它可以获得相当大的性能收益。
如果有一种方法可以直接访问内核空间中的缓冲区,那么我们可以跳过用户空间中的这个临时缓冲区。Java NIO提供了一种这样做的方法。
ByteBuffer是Java NIO提供的几个缓冲区之一。它只是一个用于读取数据或写入数据的容器或容器。上述行为是通过在buffer上使用allocateDirect() API分配一个直接缓冲区来实现的。
Java文档中的字节缓冲区有有用的信息。
这里有一篇很好的文章解释了ByteBuffer的好处。本文的重点如下:
ByteBuffer的第一个优点,不管它是直接的还是间接的,都是对结构化二进制数据的高效随机访问(例如,在一个答案中所述的低级IO)。在Java 1.4之前,要读取这样的数据,可以使用DataInputStream,但没有随机访问。
以下是直接ByteBuffer/MappedByteBuffer的好处。注意,直接缓冲区是在堆之外创建的:
Unaffected by gc cycles: Direct buffers won't be moved during garbage collection cycles as they reside outside of heap. TerraCota's BigMemory caching technology seems to rely heavily on this advantage. If they were on heap, it would slow down gc pause times. Performance boost: In stream IO, read calls would entail system calls, which require a context-switch between user to kernel mode and vice versa, which would be costly especially if file is being accessed constantly. However, with memory-mapping this context-switching is reduced as data is more likely to be found in memory (MappedByteBuffer). If data is available in memory, it is accessed directly without invoking OS, i.e., no context-switching.
请注意,mappedbytebuffer非常有用,特别是当文件很大并且频繁访问少数组块时。
页面共享:内存映射文件可以在进程之间共享,因为它们分配在进程的虚拟内存空间中,并且可以跨进程共享。
推荐文章
- 如何格式化Joda-Time DateTime仅为mm/dd/yyyy?
- 如何在POM.xml中引用环境变量?
- 如何在android中复制一个文件?
- 将整数转换为字符串,以逗号表示千
- 接口方法的最终参数-有什么意义?
- Java中的@UniqueConstraint注释
- 如何在清洁模式下运行eclipse ?如果我们这样做会发生什么?
- 获取java.lang.ClassNotFoundException: org.apache.commons.logging.LogFactory异常
- Java中的正则表达式命名组
- c#和Java的主要区别是什么?
- 什么是NullPointerException,我如何修复它?
- 在Java中使用“final”修饰符
- 无法在Flutter上找到捆绑的Java版本
- 如何在Kotlin解析JSON ?
- 如何在新的材质主题中改变背面箭头的颜色?