【问题标题】:Slicing byte arrays in Java在 Java 中切片字节数组
【发布时间】:2013-08-21 20:56:35
【问题描述】:

我正在尝试对字节数组进行切片以修剪数组的第一部分。我正在使用 ByteBuffer,但它的行为不像我预期的那样。

byte[] myArray = new byte[10];
ByteBuffer buf = ByteBuffer.wrap(myArray);
buf.position(5);
ByteBuffer slicedBuf = buf.slice();
byte[] newArray = slicedBuf.array();

我希望 newArray 的大小为 5,只包含我的 ByteBuffer 的最后一部分。而是返回完整的字节数组。我知道这是因为“后备缓冲区”一直都是一样的。

如何切片以仅包含数组的所需部分?

编辑:添加上下文

字节是从网络接收的。缓冲区是这样形成的:

[ SHA1 hash ] [ data... lots of it ]

我已经有一个以字节数组为参数并计算 SHA1 哈希的函数。我想要的是对整个缓冲区进行切片,只传递没有预期哈希的数据。

【问题讨论】:

  • 如果你没有编写散列函数,如果你想避免复制,一旦你把所有东西都放在一个byte[] 中,你就会有点卡住了。为什么不将网络中的哈希值读入一个数组,然后将数据读入另一个?

标签: java


【解决方案1】:

您可以使用Arrays.copyOfRange 方法。例如:

// slice from index 5 to index 9
byte[] slice = Arrays.copyOfRange(myArray, 5, 10);

【讨论】:

  • 感谢您的回答。您知道是否有任何方法可以在不复制的情况下做到这一点?我的数组可以达到许多兆字节,所以我宁愿尽可能避免复制
  • 字节数组中的字节不能被不同的数组重用。为此,您有 ByteBuffer 类。或者,更改您的 SHA1 函数,使其接受除数组之外的切片的偏移量和长度。
  • 我不认为我可以更改我的哈希算法,因为它是 javax.crypto.mac。我无法控制传递给它的参数。
  • 使用update(byte[],int,int)方法(docs.oracle.com/javase/7/docs/api/javax/crypto/…
【解决方案2】:

您创建的ByteBuffer 由该数组支持。当您致电slice() 时,您实际上会收到该数据的特定视图

创建一个新的字节缓冲区,其内容是该缓冲区内容的共享子序列。

因此,在返回的 ByteBuffer 上调用 array() 会返回整个支持数组。

要从该视图中提取所有字节,您可以这样做:

byte[] bytes = new byte[slicedBuf.remaining()];
slicedBuf.read(bytes);

该视图中的字节将被复制到新数组中。

编辑以从下面的 cmets 添加: 值得注意的是,如果您感兴趣的只是将字节从一个 byte[] 复制到另一个 byte[],则没有理由使用 @ 987654328@;只需复制字节。

【讨论】:

  • 基本上,如果您的答案中存在ByteBuffer 这个词,那么这是一个糟糕的答案。请参阅 Joni 的答案以获得最糟糕的(并且是唯一可接受的恕我直言)答案。
  • 我回答了 OP 的问题,而不是对他意图的解释。此外,如果您的答案没有任何内容来解释为什么会起作用,那么这是一个糟糕的答案。
  • 是的,谢谢您的回答。我正在从 C 移植代码,我没有任何复制,只有指针操作,所以我期待在 Java 中有类似的东西。我的数组可以达到很多兆字节,所以复制非常浪费
  • @Eric - 是的,Java 是……不同的。如果你试图避免复制,我需要更多关于字节代表什么以及你试图用它们做什么的上下文。
猜你喜欢
  • 2019-07-30
  • 1970-01-01
  • 2020-10-02
  • 2018-02-05
  • 2012-11-10
  • 1970-01-01
  • 2021-10-29
  • 1970-01-01
  • 2011-05-30
相关资源
最近更新 更多