자바에서 바이트 배열 형태로 일부 상수 값 (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.Hex
은 String
y 16 진과 2 진 사이를 변환하는 데 유용한 API가있는 것입니다 . 예를 들면 다음과 같습니다.
-
Hex.decodeHex(char[] data)
DecoderException
배열에 16 진수가 아닌 문자가 있거나 홀수 개의 문자가 있으면를 던집니다 . -
Hex.encodeHex(byte[] data)
는 위의 디코딩 방법에 대응하며char[]
. -
Hex.encodeHexString(byte[] data)
byte
배열에서를 다시로 변환 합니다String
.
용법: Hex.decodeHex("dd645a2564cbe648c8336d2be5eafaa6".toCharArray())