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非常有用,特别是当文件很大并且频繁访问少数组块时。
页面共享:内存映射文件可以在进程之间共享,因为它们分配在进程的虚拟内存空间中,并且可以跨进程共享。
推荐文章
- 如何创建数组列表的数组?
- noclassdeffounderror:无法初始化类XXX
- 如何创建今天午夜和明天午夜的Java日期对象?
- ByteBuffer在Java中的用途是什么?
- 使Hibernate忽略未映射的实例变量
- 映射enum在JPA与固定的值?
- 如何找到可用的端口?
- 假唤醒在Java中真的发生了吗?
- 如何按字母顺序排序列表?
- 如何在java中格式化持续时间?(如格式H:MM:SS)
- urlencoder .encode(字符串)已弃用,我应该使用什么代替?
- javax.transaction.Transactional vs . org.springframework.transaction.annotation.Transactional
- Java 8接口方法中不允许“同步”的原因是什么?
- 如何找到Java堆大小和内存使用(Linux)?
- 使用Enum实现单例(Java)