从字节缓冲区中提取值

Posted

技术标签:

【中文标题】从字节缓冲区中提取值【英文标题】:Extract Values from Byte Buffer 【发布时间】:2020-05-07 15:17:54 【问题描述】:

我正在尝试将值从一个字节缓冲区放入另一个字节缓冲区。假设源字节缓冲区的限制为 20KB,并且其中存在的值仅到 8kb,例如:1,2,3,4.... 到 8kb 之后为 0,0,0,0,0,.. .直到20kb 现在我只想将 8kb 值复制到目标字节缓冲区而不是“0”值。

下面是尝试过的代码。

ByteBuffer src = ByteBuffer.allocate(20000);
ByteBuffer dst = ByteBuffer.allocate(32000);
//Adding values to src till 8kb

byte[] b = new byte[src.position()];
src.get(b, 0, b.length); // to get the values from src byte buffer to byte array
if(dst.remaining() > b.length)
    dst.put(b); // to put values got from src to dst

src.clear(); // to empty the src

在此我没有得到 src 中的字节数组中的值。我在字节数组中得到 0,0,0,0,0....。

谁能帮我解决这个问题,如何将字节缓冲区中的值复制到另一个而不得到空值。即空的。

【问题讨论】:

你能用只有 10 字节的缓冲区试试这个,看看调试器中发生了什么?诊断起来会容易得多。 如果将源缓冲区填充到 8kB,那么它的位置应该是 8kB,而它的限制应该仍然是 20kB。所以只需翻转源缓冲区,使其位置为 0 并限制为 8kB,然后将源缓冲区放入目标缓冲区(例如 target.put(source.flip()),注意如果 target 没有足够的空间,则可能会抛出 BufferOverflowException)。 【参考方案1】:

当您用 8kb 的数据填充 src 时,将 8kb 处的位置放入 20000 大小的缓冲区中。

然后您调用src.get(b, 0, b.length),它会尽职地将价值 8kb 的数据(因为 b.length = 8kb)复制到 b 数组中...从当前位置开始,即 8kb in。因此,它将字节 [8192,16384) 复制到您的字节数组中。当然,它们都是零。

那么,你如何解决它?

这正是flip() 缓冲区方法的用途:从“写”模式切换到“读”模式。在 src 获得 8kb 的数据后,翻转你的缓冲区(此时 position() 为 0,limit() 现在是原来的位置,即 8kb),这样就可以了。

然后回到开始模式(准备写入高达 20000 的值到缓冲区中),清除它。

这就是缓冲区的流程:

您从位置 = 0,限制 = 20000 开始。 您将一些数据(在本例中为 8192)读入缓冲区。在某些时候,pos = 8192,limit = 20000。 你翻转:pos 现在是 0,limit = 8192,容量 = 20000。 您将所有 8192 读入其他内容; pos 现在是 8192,limit 是 8192,cap 是 20000。 你清除 pos 现在是 0,容量是 20000,是限制。 再次回到起点。你可以永远这样做。

所以,写入缓冲区,翻转,读取,清除,写入,翻转,读取,清除 - 永远。

编辑:我错误地认为 flip() 也会将您从“读取模式”转换回写入模式。它并没有真正做到这一点,清楚更好,更新答案以反映这一点。

【讨论】:

以上是关于从字节缓冲区中提取值的主要内容,如果未能解决你的问题,请参考以下文章

如何从 ByteBuffer 中提取使用过的字节数组?

C#,从 USART 接收字符缓冲区中提取双精度

直接字节缓冲区

将固定字节从输入流存储到字节数组中

有效计算 arm neon 中 16 字节缓冲区中不同值的数量

FFmpeg 跳过渲染帧