【问题标题】:What is the use of ByteBuffer in Java? [closed]Java中的ByteBuffer有什么用? [关闭]
【发布时间】:2011-06-18 00:00:42
【问题描述】:

ByteBuffer 在 Java 中的示例应用程序是什么?请列出使用此功能的任何示例场景。

【问题讨论】:

  • Apache Hadoop 的压缩(例如 zlib 编解码器)使用来自 jave.nio 的 ByteBuffer。
  • 适合向 GPU 发送数据。
  • StackOverFlow:“这个问题没有用,因此它已关闭”。我:点赞

标签: java buffer bytebuffer


【解决方案1】:

This 很好地描述了它的用途和缺点。当您需要进行快速的低级 I/O 时,您基本上都会使用它。如果您要实现 TCP/IP 协议或者如果您正在编写数据库 (DBMS),那么这个类会派上用场。

【讨论】:

【解决方案2】:

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

【讨论】:

  • 这条评论的大部分内容是从java 7 docs复制而来的。
  • 除非您利用了不明显的副作用,否则我相信您可能使用了错误的绝对看跌方法。 Javadoc 似乎表明绝对 put 需要一个索引值。
  • 即使它只是 api doc 的副本,它的分数也是值得的,有些人似乎懒得看它。
  • 其中一个例子有错误。 “绝对看跌”,错过了代表索引的第一个参数(在本例中为 0)。
【解决方案3】:

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

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

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

Java Documentation of Byte Buffer has useful information.

【讨论】:

    【解决方案4】:

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

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

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

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

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

    请注意,MappedByteBuffers 非常有用,尤其是在文件很大并且访问更频繁的几组块时。

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

    【讨论】:

      【解决方案5】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-11-23
        • 1970-01-01
        • 2011-03-27
        • 1970-01-01
        • 2012-09-02
        • 2012-07-10
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多