【问题标题】:Concat two ByteBuffers in Java在 Java 中连接两个 ByteBuffer
【发布时间】:2014-06-06 19:56:32
【问题描述】:

如何将两个 ByteBuffer 连接到一个 ByteBuffer?

以下不起作用:

    ByteBuffer bb = ByteBuffer.allocate(100);
    ByteBuffer bb2 = ByteBuffer.allocate(200);
    bb.allocate(200).put(bb2);
    System.out.println(bb.array().length);

bb的长度还是100

【问题讨论】:

    标签: java bytebuffer


    【解决方案1】:

    试试下面的代码:

    //store both ByteBuffer object as an array
    byte[] array1 = ByteBuffer.allocate(100).array();
    byte[] array2 = ByteBuffer.allocate(200).array();
    
    //create a ByteBuffer which is big enough
    ByteBuffer bigenough = ByteBuffer.allocate(array1.length + array2.length);
    
    //put the two arrays in one ByteBuffer
    ByteBuffer after1 = bigenough.put(array1, 0, array1.length);
    ByteBuffer result = after1.put(array2, array1.length, array2.length);
    
    //print the length of the combined array.
    System.out.println(result.array().length);
    

    【讨论】:

    • 结果的长度为 200。我预计是 300。
    • 我改进了分析器。但是您是否考虑过仅组合数组本身? ByteBuffer 是否必须使用?
    【解决方案2】:

    有点像

    bb = ByteBuffer.allocate(300).put(bb).put(bb2);
    

    应该做的工作是:创建一个足够大的缓冲区来容纳两个缓冲区的内容,然后使用相关的 put-methods 用第一个和第二个缓冲区填充它。 (顺便说一句,put 方法返回调用该方法的实例)

    【讨论】:

    • 警告: positionlimit 都将设置为 capacity,这可能不是您所期望或想要的您将进一步处理生成的ByteBuffer。您将需要调用.flip(),以便能够通过在末尾添加.flip(); 来处理返回的ByteBuffer 的全部内容。
    • 是的,flip()position(0)(我个人觉得后者更具可读性)
    【解决方案3】:

    我们将复制所有数据。请记住,这就是字符串连接代价高昂的原因!

    public static ByteBuffer concat(final ByteBuffer... buffers) {
        final ByteBuffer combined = ByteBuffer.allocate(Arrays.stream(buffers).mapToInt(Buffer::remaining).sum());
        Arrays.stream(buffers).forEach(b -> combined.put(b.duplicate()));
        return combined;
    }
    

    【讨论】:

      【解决方案4】:

      你可以使用这里的方法

      https://github.com/ata4/ioutils/blob/047e401d73c866317af2e12f7803b3ee43eec80a/src/main/java/info/ata4/io/buffer/ByteBufferUtils.java#L289

      例如:

        ByteBuffer concat() {
      int length = 0;
      for (ByteBuffer bb : buffers) {
        bb.rewind();
        length += bb.remaining();
      }
      ByteBuffer bbNew = ByteBuffer.allocateDirect((int) length);
      
      // put all buffers from list
      for (ByteBuffer bb : buffers) {
        bb.rewind();
        bbNew.put(bb);
      
      }
      bbNew.rewind();
      return bbNew;
      }
      

      【讨论】:

        【解决方案5】:

        可能是因为在第 3 行,即 bb.allocate(200).put(bb2);

        bb.allocate(200) 正在返回一个新的字节缓冲区(请参阅https://docs.oracle.com/javase/7/docs/api/java/nio/ByteBuffer.html#allocate(int))。这实际上并没有改变bb 本身。所以它仍然是 line1 容量为 100 的字节缓冲区。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-12-19
          • 1970-01-01
          • 2010-09-09
          • 1970-01-01
          • 2011-04-14
          相关资源
          最近更新 更多