2011-01-30 70 views

回答

98

This是它的用途和缺点的一个很好的说明。每当你需要做快速的低级I/O时,你都会使用它。如果你打算实现一个TCP/IP协议,或者你正在编写一个数据库(DBMS),这个类将派上用场。

+2

在使用Java和Cassandra DB开发的高流量网站中它有用吗? – Aklin 2011-01-30 05:38:35

+1

快速搜索后,似乎是的,Cassandra确实使用了ByteBuffer:http://www.mail-archive.com/[email protected]/msg14967.html如果您想知道一个原始网站,那么可能是,但通常它只会间接地被网站使用 - 通过使用像cassandra – kelloti 2011-01-30 05:48:43

78

ByteBuffer类很重要,因为它构成了在Java中使用通道的基础。 字节缓冲区类在字节缓冲器限定六类操作:

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

  • 相对bulk get方法,从这个缓冲到一个数组传输的字节的连续序列;

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

  • 绝对和相对get和put方法和写入其他原始类型的值,将它们转换到和从在一个特定的字节顺序的字节序列;

  • 方法用于创建视图缓冲剂,其允许含有其他原语类型的值的缓冲器要观看的字节缓冲器;和

  • 方法为compacting,duplicatingslicing一个字节缓冲区。

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 
13

在Android中可以创建和Java℃之间共享缓冲器++(以directAlloc法)和操纵它在两侧。

12

使用面向流的API的JAVA IO使用缓冲区作为用户空间内数据的临时存储。通过DMA从磁盘读取的数据首先被复制到内核空间的缓冲区中,然后再传送到用户空间的缓冲区。因此有开销。避免它可以在性能上获得可观的收益。

我们可以跳过用户空间这个临时缓冲区,如果有直接的方式访问缓冲区在内核空间。 JAVA NIO提供了这样做的方法。

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

Java Documentation of Byte Buffer has useful information.

6

Here是一个伟大的文章,解释ByteBuffer的好处。以下是文章的关键点:字节缓冲区的

  • 先发优势,而不论它是直接或间接的被结构化的二进制数据(例如,低级别的IO如在一个规定的高效的随机存取答案)。在Java 1.4之前,要读取这样的数据,可以使用DataInputStream,但不能随机访问。

以下是专门针对直接ByteBuffer/MappedByteBuffer的好处。需要注意的是直接缓冲区堆之外创建:

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

  2. 性能升压:在流IO,读呼叫将需要系统调用,这需要用户之间的上下文切换到内核模式,反之亦然,这将是昂贵的,特别是如果正在不断访问的文件。但是,使用内存映射时,这种上下文切换会减少,因为数据更有可能在内存中找到(MappedByteBuffer)。如果数据在内存中可用,则直接访问它而不调用OS,即不进行上下文切换。

请注意,MappedByteBuffers非常有用,特别是如果文件很大并且块的访问次数更少。

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