web-dev-qa-db-fra.com

Existe-t-il un équivalent de memcpy () en Java?

J'ai un octet [] et j'aimerais le copier dans un autre octet []. Je montre peut-être mon arrière-plan 'C' simple, mais existe-t-il un équivalent de memcpy () sur les tableaux d'octets en Java?

70
simon

Vous pouvez essayer System.arraycopy ou utiliser des fonctions de tableau de la classe Arrays comme Java.util.Arrays.copyOf. Les deux devraient vous donner une performance native sous le capot.

Arrays.copyOf est probablement favorable à la lisibilité, mais n’a été introduit que dans Java 1.6.

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

Utilisez System.arraycopy ()

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

Exemple,

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


.__ ou utilisez Arrays.copyOf ()
Exemple,

target = Arrays.copyOf(source, length);

Java.util.Arrays.copyOf(byte[] source, int length) a été ajouté à JDK 1.6.

La méthode copyOf() utilise System.arrayCopy() pour créer une copie du tableau, mais elle est plus souple que clone(), car vous pouvez créer des copies de parties d'un tableau.

89
Zaki

Si vous voulez juste une copie exacte d'un tableau à une dimension, utilisez clone() .

byte[] array = { 0x0A, 0x01 };
byte[] copy = array.clone();

Pour les autres opérations de copie de tableau, utilisez System.arrayCopyArrays.copyOf comme suggère Tom .

_/En général, clone devrait être évité, mais il s'agit d'une exception à la règle.

7
McDowell

Vous pouvez utiliser System.arrayCopy . Il copie les éléments d'un tableau source vers un tableau de destination. L'implémentation Sun utilise un assembleur optimisé manuellement, ce qui est rapide.

5
mdma

Java a en fait quelque chose comme memcpy (). La classe Unsafe a une méthode copyMemory () qui est essentiellement identique à memcpy (). Bien sûr, comme memcpy (), il ne fournit aucune protection contre les superpositions de mémoire, la destruction de données, etc. On ne sait pas s'il s'agit vraiment d'un memcpy () ou d'un memmove (). Il peut être utilisé pour copier des adresses réelles vers des adresses réelles ou des références à des références. Notez que si des références sont utilisées, vous devez fournir un décalage (sinon la JVM mourra dès que possible). 

Unsafe.copyMemory () fonctionne (jusqu'à 2 Go par seconde sur mon vieux PC fatigué). À utiliser à vos risques et périls. Notez que la classe Unsafe n'existe pas pour toutes les implémentations JVM.

3
Peter Schaeffer

Vous pouvez utiliser System.arraycopy

2
Artem Barger

N ° Java n'a pas d'équivalent à memcpy. Java a un équivalent de memmove à la place.

Si les arguments src et dest font référence au même objet tableau, la copie est effectuée comme si les composants situés aux positions srcPos à srcPos + longueur-1 étaient d'abord copiés dans un tableau temporaire avec des composants de longueur copié dans les positions destPos à travers destPos + longueur-1 du tableau de destination.

Documents Oracle

Il est très probable que System.arraycopy n'aura jamais les mêmes performances que memcpy si src et dest font référence au même tableau. Habituellement, ce sera assez rapide cependant.

1

Utilisez byteBufferViewVarHandle ou byteArrayViewVarHandle.

Cela vous permettra de copier un tableau de "longs" directement dans un tableau de "doubles" et similaire avec quelque chose comme:

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());

Cela vous permettra de faire le bit de piratage comme:

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