快速擦除(不清楚)Java 中的 ByteBuffer
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11197875/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Fast erase (not clear) a ByteBuffer in Java
提问by asksw0rder
I am trying to "clean up" a ByteBuffer
to be all zero bytes (all 0x00
). I tried to loop over all positions in the buffer and set them to 0x00
, but the efficiency is bad. Is there any better way to quickly clear a ByteBuffer
- similar to what BitSet.clear()
does?
我正在尝试“清理” aByteBuffer
以使其全部为零字节(全部0x00
)。我试图遍历缓冲区中的所有位置并将它们设置为0x00
,但效率很差。有没有更好的方法来快速清除ByteBuffer
- 类似于什么BitSet.clear()
?
Please note that ByteBuffer.clear()
is not an appropriate solution for me in this scenario--I have to erase all the data inside of the buffer, and not just reset the pointer to the beginning.
请注意,ByteBuffer.clear()
在这种情况下,这对我来说不是一个合适的解决方案——我必须擦除缓冲区内的所有数据,而不仅仅是将指针重置到开头。
Any hints?
任何提示?
Edit: the ByteBuffer is used as a part of the hash table, and it maintains the references of the hash table entries. Every time when the hash table needs to be flushed, I have to reset the hash table entries for later hash table insertion. Since the hash table is accessed in a random-fashion, I cannot simply clear() the state of the byte buffer.
编辑:ByteBuffer 用作哈希表的一部分,它维护哈希表条目的引用。每次需要刷新哈希表时,我都必须重置哈希表条目以供以后插入哈希表。由于哈希表是以随机方式访问的,我不能简单地 clear() 字节缓冲区的状态。
采纳答案by DNA
Have you tried using one of the ByteBuffer.put(byte[])
or ByteBuffer.put(ByteBuffer)
methods to write multiple zeros in one go? You could then iterate over the buffer in chunks of 100 or 1000 bytes, or whatever, using an array or buffer pre-filled with zeros.
您是否尝试过使用ByteBuffer.put(byte[])
或ByteBuffer.put(ByteBuffer)
方法之一一次性写入多个零?然后,您可以使用预先填充零的数组或缓冲区,以 100 或 1000 字节的块或其他任何方式遍历缓冲区。
Downside: this is an optional operation, so not all implementations of ByteBuffer are required to provide it...
缺点:这是一个可选操作,因此并非所有 ByteBuffer 的实现都需要提供它...
回答by Jim Garrison
For ByteBuffer
implementations that provide the optional array()
method (where hasArray()
returns true
), you could use this method get a reference to the underlying array, then use java.util.Arrays#fill()
.
对于ByteBuffer
提供可选array()
方法(其中hasArray()
返回true
)的实现,您可以使用此方法获取对底层数组的引用,然后使用java.util.Arrays#fill()
.
回答by Trevor Robinson
As DNA mentions, having a pre-filled buffer and using ByteBuffer.put(ByteBuffer)
is probably the fastest portable way. If that's not practical, you can do something like this to take advantage of either Arrays.fill
or Unsafe.putLong
when applicable:
正如 DNA 所提到的,预先填充缓冲液并使用ByteBuffer.put(ByteBuffer)
可能是最快的便携方式。如果这不切实际,你可以做这样的事情来利用Arrays.fill
或Unsafe.putLong
在适用时:
public static void fill(ByteBuffer buf, byte b) {
if (buf.hasArray()) {
final int offset = buf.arrayOffset();
Arrays.fill(buf.array(), offset + buf.position(), offset + buf.limit(), b);
buf.position(buf.limit());
} else {
int remaining = buf.remaining();
if (UNALIGNED_ACCESS) {
final int i = (b << 24) | (b << 16) | (b << 8) | b;
final long l = ((long) i << 32) | i;
while (remaining >= 8) {
buf.putLong(l);
remaining -= 8;
}
}
while (remaining-- > 0) {
buf.put(b);
}
}
}
Setting UNALIGNED_ACCESS
requires some knowledge of your JRE implementation and platform. Here's how I would set it for the Oracle JRE when also using JNA (which provides Platform.ARCH
as a convenient, canonical way to access the os.arch
system property).
设置UNALIGNED_ACCESS
需要您的 JRE 实现和平台的一些知识。下面是我在也使用 JNA 时为 Oracle JRE 设置它的方法(它提供Platform.ARCH
了一种方便的、规范的方式来访问os.arch
系统属性)。
/**
* Indicates whether the ByteBuffer implementation likely supports unaligned
* access of multi-byte values on the current platform.
*/
private static final boolean UNALIGNED_ACCESS = Platform.ARCH.startsWith("x86");
回答by Alex Cohn
If you need a fresh clean zero-filled ByteBuffer
after the hash table is flushed, the easiest way is to drop the existing ByteBuffer
and allocate a new one. The official documentation does not say so, but all known implementations zero the memory of new buffers. See http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6535542for additional info.
如果ByteBuffer
在刷新哈希表后需要一个全新的零填充,最简单的方法是删除现有的ByteBuffer
并分配一个新的。官方文档没有这么说,但所有已知的实现都将新缓冲区的内存归零。有关其他信息,请参阅http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6535542。