Как инициализировать массив байтов в Java?
Мне нужно сохранить некоторые константные значения (UUID) в форме массива байтов в java, и мне интересно, какой лучший способ инициализировать эти статические массивы. Вот как я это делаю сейчас, но я чувствую, что должен быть лучший способ.
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" };
Ответы
Ответ 1
Используя функцию, преобразующую шестнадцатеричную строку в byte[]
, вы можете сделать
byte[] CDRIVES = hexStringToByteArray("e04fd020ea3a6910a2d808002b30309d");
Я бы предложил использовать функцию, определенную Dave L в Преобразовать строковое представление шестнадцатеричного дампа в массив байтов, используя Java?
Я вставляю его здесь для максимальной читаемости:
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
, падение производительности не имеет значения.
Ответ 2
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();
Ответ 3
В 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 слишком мал, когда вы используете небольшие массивы. Но у Guava есть также версии, которые могут анализировать входные потоки. Это хорошая функция при работе с большими шестнадцатеричными входами.
Ответ 4
Вы можете использовать класс Java UUID для хранения этих значений вместо байтовых массивов:
UUID
public UUID(long mostSigBits,
long leastSigBits)
Создает новый UUID с использованием указанных данных. mostSigBits используется для наиболее значимых 64 бит UUID, а наименьшие SigBits становятся наименее значимыми 64 битами UUID.
Ответ 5
Что касается чистого процесса, вы можете использовать ByteArrayOutputStream объект...
ByteArrayOutputStream bObj = new ByteArrayOutputStream();
bObj.reset();
//записываем все значения в bObj один за другим, используя
bObj.write(byte value)
//по завершении вы можете получить байт [], используя
CDRIVES = bObj.toByteArray();
//, чтобы повторить аналогичный процесс для CMYDOCS и IEFRAME,
ПРИМЕЧАНИЕ Это не эффективное решение, если у вас действительно есть небольшой массив.
Ответ 6
Мой предпочтительный вариант в этом случае - использовать org.apache.commons.codec.binary.Hex
, который имеет полезные API для преобразования между String
y hex и двоичным. Например:
-
Hex.decodeHex(char[] data)
, который выдает a DecoderException
, если в массиве есть не-шестнадцатеричные символы или есть нечетное число символов.
-
Hex.encodeHex(byte[] data)
является аналогом описанного выше метода декодирования и выплескивает char[]
.
-
Hex.encodeHexString(byte[] data)
, который преобразует обратно из массива byte
в String
.
Использование: Hex.decodeHex("dd645a2564cbe648c8336d2be5eafaa6".toCharArray())
Ответ 7
Решение без библиотек, возвращаемая динамическая длина, целая интерпретация без знака (не два дополнения)
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 };
}
}
Ответ 8
Вы можете использовать эту служебную функцию:
public static byte[] fromHexString(String src) {
byte[] biBytes = new BigInteger("10" + src.replaceAll("\\s", ""), 16).toByteArray();
return Arrays.copyOfRange(biBytes, 1, biBytes.length);
}
В отличие от вариантов Denys Séguret и stefan.schwetschke, он позволяет вставлять символы разделителя (пробелы, символы табуляции и т.д.) Во входную строку, делая ее более удобочитаемой.
Пример использования:
private static final byte[] CDRIVES
= fromHexString("e0 4f d0 20 ea 3a 69 10 a2 d8 08 00 2b 30 30 9d");
private static final byte[] CMYDOCS
= fromHexString("BA8A0D4525ADD01198A80800361B1103");
private static final byte[] IEFRAME
= fromHexString("80531c87 a0426910 a2ea0800 2b30309d");
Ответ 9
private static final int[] CDRIVES = new int[] {0xe0, 0xf4, ...};
и после обращения к байту.
Ответ 10
byte[] responseBody = "Invalid Domain Alias".getBytes();