Java中是否有等同于memcpy()的东西?


81

我有一个byte [],想将其复制到另一个byte []中。也许我在这里展示了我简单的“ C”背景,但是在Java字节数组中是否有等同于memcpy()的东西?

Answers:


84

您可以尝试System.arraycopy或使用阵列功能,在Arrays像类java.util.Arrays.copyOf。两者都应在引擎盖下为您提供本机性能。

Arrays.copyOf可能对可读性有利,但仅在Java 1.6中引入。

 byte[] src = {1, 2, 3, 4};
 byte[] dst = Arrays.copyOf(src, src.length);
 System.out.println(Arrays.toString(dst));

我认为第二种选择更“合乎逻辑”。我从来不明白为什么System.arraycopy()在哪里,这是最笨拙的位置之一。
sinuhepop

@Sinuhe-出于历史原因在那儿。
斯蒂芬·C

29
这不是正确的答案。memcpy()不分配数据,仅复制到现有缓冲区。而Arrays.copyOf()显然会分配新的内存。
splinux

102

使用System.arraycopy()

System.arraycopy(sourceArray, 
                 sourceStartIndex,
                 targetArray,
                 targetStartIndex,
                 length);

例,

String[] source = { "alpha", "beta", "gamma" };
String[] target = new String[source.length];
System.arraycopy(source, 0, target, 0, source.length);


或使用Arrays.copyOf()
示例,

target = Arrays.copyOf(source, length);

java.util.Arrays.copyOf(byte[] source, int length)是在JDK 1.6中添加的。

copyOf()方法用于System.arrayCopy()制作数组的副本,但是比clone()您可以制作数组部分的副本更灵活。


5
Arrays.copyOf()也分配内存。在您的示例中,如果您更改String [] target = new String [4]; 然后target = Arrays.copyOf()创建一个新的目标,它是String [3]。不是内存复制行为。
MikeF

Arrays.copyOf内部使用System.arraycopy,这是一种本地方法。
Gajraj Tanwar


5

您可以使用System.arrayCopy。它将元素从源数组复制到目标数组。Sun实施使用手动优化的汇编器,因此速度很快。


3

Java实际上确实像memcpy()一样。Unsafe类具有copyMemory()方法,该方法与memcpy()基本上相同。当然,与memcpy()一样,它也不提供对内存覆盖,数据破坏等的保护。目前尚不清楚它是memcpy()还是memmove()。它可用于从实际地址复制到实际地址或从引用复制到引用。请注意,如果使用引用,则必须提供一个偏移量(否则JVM将尽快终止)。

Unsafe.copyMemory()可以正常工作(在旧的旧PC上每秒高达2 GB)。使用风险自负。请注意,并非所有JVM实现都存在Unsafe类。


很抱歉在这个古老的主题上使用了所有的宠物护理方法,但是您能否给我一个有关如何使用一系列参考文献的示例。而且,对于少量数据(例如1-4 MB)还是更快,还是在您提到的2GB之类的较大数据的情况下才值得呢?
FinnTheHuman

2
使用sun.misc.Unsafe该类被认为是不好的习惯,因为它是私有包类。另外,从Java 9开始,它将不再可用,因此尝试使用此类与请求代码意外中断相同。
code_dredd


0

使用byteBufferViewVarHandle或byteArrayViewVarHandle。

这样,您就可以将“ longs”数组直接复制到“ doubles”数组中,并且类似以下内容:

public long[] toLongs(byte[] buf) {
    int end = buf.length >> 3;
    long[] newArray = new long[end];
    for (int ii = 0; ii < end; ++ii) {
        newArray[ii] = (long)AS_LONGS_VH.get(buf, ALIGN_OFFSET + ii << 3);
    }
}

private static final ALIGN_OFFSET = ByteBuffer.wrap(new byte[0]).alignmentOffset(8); 
private static final VarHandle AS_LONGS_VH = MethodHandles.byteArrayViewVarHandle(long[].class, ByteOrder.nativeOrder());

这将使您可以像以下那样进行一些黑客攻击:

float thefloat = 0.4;
int floatBits;
_Static_assert(sizeof theFloat == sizeof floatBits, "this bit twiddling hack requires floats to be equal in size to ints");
memcpy(&floatBits, &thefloat, sizeof floatBits);

0

。Java没有与的等效项memcpy。Java等效于Java memmove

如果src和dest参数引用相同的数组对象,则执行复制,就好像先将srcPos到srcPos + length-1位置上的分量复制到具有长度分量的临时数组,然后将临时数组的内容通过目标数组的destPos + length-1复制到位置destPos。

Oracle文档

这是非常有可能System.arraycopy将永远不会有相同的性能,memcpy如果srcdest指向同一个阵列。通常,这将足够快。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.