[java] Java에서 바이트 배열을 어떻게 초기화합니까?

자바에서 바이트 배열 형태로 일부 상수 값 (UUID)을 저장해야하며 정적 배열을 초기화하는 가장 좋은 방법이 무엇인지 궁금합니다. 이것이 내가 현재하고있는 방법이지만 더 나은 방법이 있어야한다고 생각합니다.

private static final byte[] CDRIVES = new byte[] { (byte)0xe0, 0x4f, (byte)0xd0,
    0x20, (byte)0xea, 0x3a, 0x69, 0x10, (byte)0xa2, (byte)0xd8, 0x08, 0x00, 0x2b,
    0x30, 0x30, (byte)0x9d };
private static final byte[] CMYDOCS = new byte[] { (byte)0xba, (byte)0x8a, 0x0d,
    0x45, 0x25, (byte)0xad, (byte)0xd0, 0x11, (byte)0x98, (byte)0xa8, 0x08, 0x00,
    0x36, 0x1b, 0x11, 0x03 };
private static final byte[] IEFRAME = new byte[] { (byte)0x80, 0x53, 0x1c,
    (byte)0x87, (byte)0xa0, 0x42, 0x69, 0x10, (byte)0xa2, (byte)0xea, 0x08,
    0x00, 0x2b, 0x30, 0x30, (byte)0x9d };
...
and so on

비효율적이지만 깨끗하게 보일 수있는 것이 있습니까? 예를 들면 다음과 같습니다.

private static final byte[] CDRIVES =
    new byte[] { "0xe04fd020ea3a6910a2d808002b30309d" };



답변

에 헥사 문자열을 변환하는 기능을 사용하면 byte[], 당신은 할 수

byte[] CDRIVES = hexStringToByteArray("e04fd020ea3a6910a2d808002b30309d");

Dave L이 정의한 함수를 사용하는 것이 좋습니다. Java를 사용하여 16 진 덤프의 문자열 표현을 바이트 배열 변환 .

가독성을 극대화하기 위해 여기에 삽입합니다.

public static byte[] hexStringToByteArray(String s) {
    int len = s.length();
    byte[] data = new byte[len / 2];
    for (int i = 0; i < len; i += 2) {
        data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
                             + Character.digit(s.charAt(i+1), 16));
    }
    return data;
}

CDRIVES static및 을 허용 final하면 성능 저하와 관련이 없습니다.


답변

byte[] myvar = "Any String you want".getBytes();

문자열 리터럴을 이스케이프하여 모든 문자를 제공 할 수 있습니다.

byte[] CDRIVES = "\u00e0\u004f\u00d0\u0020\u00ea\u003a\u0069\u0010\u00a2\u00d8\u0008\u0000\u002b\u0030\u0030\u009d".getBytes();


답변

Java 6에는 원하는 것을 정확하게 수행하는 방법이 있습니다.

private static final byte[] CDRIVES = javax.xml.bind.DatatypeConverter.parseHexBinary("e04fd020ea3a6910a2d808002b30309d")

또는 Google Guava를 사용할 수 있습니다 .

import com.google.common.io.BaseEncoding;
private static final byte[] CDRIVES = BaseEncoding.base16().lowerCase().decode("E04FD020ea3a6910a2d808002b30309d".toLowerCase());

작은 배열을 사용하면 Guava 방법이 과도합니다. 그러나 구아바에는 입력 스트림을 구문 분석 할 수있는 버전도 있습니다. 큰 16 진수 입력을 처리 할 때 유용한 기능입니다.


답변

바이트 배열 대신 Java UUID 클래스를 사용하여 이러한 값을 저장할 수 있습니다.

UUID

public UUID(long mostSigBits,
            long leastSigBits)

지정된 데이터를 사용하여 새 UUID를 구성합니다. mostSigBits는 UUID의 최상위 64 비트에 사용되며 leastSigBits는 UUID의 최하위 64 비트가됩니다.


답변

클린 프로세스에 관한 한 ByteArrayOutputStream 객체를 사용할 수 있습니다 …

ByteArrayOutputStream bObj = new ByteArrayOutputStream();
bObj.reset();

// 다음을 사용하여 모든 값을 bObj에 하나씩 쓰기

bObj.write(byte value)

// 완료되면 다음을 사용하여 바이트를 얻을 수 있습니다.

CDRIVES = bObj.toByteArray();

// CMYDOCS 및 IEFRAME에 대해서도 유사한 프로세스를 반복 할 수 있기 때문에

참고 실제로 어레이가 작은 경우에는 효율적인 솔루션이 아닙니다.


답변

라이브러리가없는 솔루션, 동적 길이가 반환 됨, 부호없는 정수 해석 (2의 보수가 아님)

    public static byte[] numToBytes(int num){
    if(num == 0){
        return new byte[]{};
    }else if(num < 256){
        return new byte[]{ (byte)(num) };
    }else if(num < 65536){
        return new byte[]{ (byte)(num >>> 8),(byte)num };
    }else if(num < 16777216){
        return new byte[]{ (byte)(num >>> 16),(byte)(num >>> 8),(byte)num };
    }else{ // up to 2,147,483,647
        return new byte[]{ (byte)(num >>> 24),(byte)(num >>> 16),(byte)(num >>> 8),(byte)num };
    }
}


답변

이 상황에서 내가 선호하는 옵션 org.apache.commons.codec.binary.HexStringy 16 진과 2 진 사이를 변환하는 데 유용한 API가있는 것입니다 . 예를 들면 다음과 같습니다.

  1. Hex.decodeHex(char[] data)DecoderException배열에 16 진수가 아닌 문자가 있거나 홀수 개의 문자가 있으면를 던집니다 .

  2. Hex.encodeHex(byte[] data)는 위의 디코딩 방법에 대응하며 char[].

  3. Hex.encodeHexString(byte[] data)byte배열에서를 다시로 변환 합니다 String.

용법: Hex.decodeHex("dd645a2564cbe648c8336d2be5eafaa6".toCharArray())