Java에서 memcpy ()에 해당하는 것이 있습니까?


81

byte []가 있고 다른 byte []에 복사하고 싶습니다. 아마도 여기에 간단한 'C'배경을 보여주고 있지만 Java의 바이트 배열에 memcpy ()와 동등한 것이 있습니까?

답변:


84

다음 과 같은 클래스 System.arraycopy에서 배열 함수를 시도 하거나 사용할 수 있습니다.Arraysjava.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 2010-07-25

@Sinuhe-역사적인 이유로 거기에 있습니다.
Stephen 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 () 문자열 [3] 인 새 대상을 만듭니다. memcopy 동작이 아닙니다.
MikeF

Arrays.copyOf는 내부적으로 네이티브 메서드 인 System.arraycopy를 사용합니다.
Gajraj Tanwar 2011


5

System.arrayCopy 를 사용할 수 있습니다 . 소스 배열의 요소를 대상 배열로 복사합니다. Sun 구현은 수작업으로 최적화 된 어셈블러를 사용하므로 빠릅니다.


3

Java에는 실제로 memcpy ()와 같은 것이 있습니다. Unsafe 클래스에는 memcpy ()와 본질적으로 동일한 copyMemory () 메서드가 있습니다. 물론 memcpy ()와 같이 메모리 오버레이, 데이터 파괴 등에 대한 보호 기능을 제공하지 않습니다. 실제로 memcpy ()인지 memmove ()인지는 명확하지 않습니다. 실제 주소에서 실제 주소로 또는 참조에서 참조로 복사하는 데 사용할 수 있습니다. 참조가 사용되는 경우 오프셋을 제공해야합니다 (그렇지 않으면 JVM이 최대한 빨리 종료됩니다).

Unsafe.copyMemory ()는 작동합니다 (오래된 피곤한 PC에서 초당 최대 2GB). 자신의 책임하에 사용하십시오. 모든 JVM 구현에 대해 Unsafe 클래스가 존재하는 것은 아닙니다.


이 고대 스레드에 대해 모든 애완 동물 세미나 리에 들어가서 미안하지만 일련의 참조를 사용하여이를 수행하는 방법에 대한 예제를 주실 수 있습니다. 그리고 소량의 데이터 (예 : 1-4MB)의 경우 더 빠르거나 언급 한 2GB와 같은 큰 데이터의 경우 가치가 있습니까?
FinnTheHuman

2
sun.misc.Unsafe클래스를 사용 하는 것은 "해킹"나쁜 습관으로 간주됩니다. b / c 개인 패키지 클래스입니다. 또한 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는 memmove대신에 동등합니다 .

src 및 dest 인수가 동일한 배열 객체를 참조하면 srcPos ~ srcPos + length-1 위치의 구성 요소가 먼저 길이 구성 요소가있는 임시 배열에 복사 된 다음 임시 배열의 내용이 복사 된 것처럼 복사가 수행됩니다. 대상 배열의 destPos + length-1을 통해 destPos 위치에 복사됩니다.

오라클 문서

그것은 매우 가능성이 System.arraycopy동일한 성능이 결코 memcpy경우를 srcdest같은 배열을 참조하십시오. 일반적으로 이것은 충분히 빠릅니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.