web-dev-qa-db-fra.com

Comment initialiser un tableau d'octets en Java?

Je dois stocker des valeurs constantes (UUID) sous forme de tableau d'octets en Java, et je me demande quel serait le meilleur moyen d'initialiser ces tableaux statiques. C’est ce que je fais actuellement, mais j’ai l’impression qu’il doit y avoir un meilleur moyen.

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

Y a-t-il quelque chose que je pourrais utiliser qui soit moins efficace, mais aurait une apparence plus propre? Par exemple:

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

En utilisant une fonction convertissant une chaîne hexa en byte[], vous pourriez faire 

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

Je vous suggère d'utiliser la fonction définie par Dave L dans Convertir une représentation sous forme de chaîne d'un vidage hexadécimal en tableau d'octets en utilisant Java?

Je l'insère ici pour une lisibilité maximale:

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;
}

Si vous laissez CDRIVES static et final, la perte de performance n’est pas pertinente. 

96
Denys Séguret
byte[] myvar = "Any String you want".getBytes();

Les littéraux de chaîne peuvent être échappés pour fournir n'importe quel caractère:

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

En Java 6, il existe une méthode qui fait exactement ce que vous voulez:

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

Vous pouvez également utiliser Google Guava :

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

La méthode de goyave est excessive, lorsque vous utilisez de petits tableaux. Mais Guava a aussi des versions qui peuvent analyser les flux d’entrée. C'est une fonctionnalité intéressante lorsqu'il s'agit de traiter de grandes entrées hexadécimales.

30

Vous pouvez utiliser la classe Java UUID pour stocker ces valeurs au lieu des tableaux d'octets:

UUID

public UUID(long mostSigBits,
            long leastSigBits)

Construit un nouvel UUID en utilisant les données spécifiées. mostSigBits est utilisé pour les 64 bits les plus significatifs de l'UUID et lessSigBits devient les 64 bits les moins significatifs de l'UUID. 

7
Mangist

En ce qui concerne le processus de nettoyage, vous pouvez utiliser ByteArrayOutputStream object ... 

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

// écrit toutes les valeurs dans bObj une par une en utilisant 

bObj.write(byte value)

// quand vous avez fini, vous pouvez obtenir l'octet [] en utilisant 

CDRIVES = bObj.toByteArray();

// que vous pouvez répéter le même processus pour CMYDOCS et IEFRAME,

NOTE Ce n'est pas une solution efficace si vous avez vraiment un petit tableau. 

2
Amit

Dans ce cas, mon option préférée consiste à utiliser org.Apache.commons.codec.binary.Hex, qui possède des API utiles pour la conversion entre Stringy hex et binaire. Par exemple:

  1. Hex.decodeHex(char[] data) qui renvoie une DecoderException s'il y a des caractères non hexadécimaux dans le tableau ou s'il existe un nombre impair de caractères.

  2. Hex.encodeHex(byte[] data) est la contrepartie de la méthode de décodage ci-dessus et crache le char[].

  3. Hex.encodeHexString(byte[] data) qui reconvertit un tableau byte en un String.

Usage: Hex.decodeHex("dd645a2564cbe648c8336d2be5eafaa6".toCharArray())

1
rbrtl

Vous pouvez utiliser cette fonction utilitaire:

public static byte[] fromHexString(String src) {
    byte[] biBytes = new BigInteger("10" + src.replaceAll("\\s", ""), 16).toByteArray();
    return Arrays.copyOfRange(biBytes, 1, biBytes.length);
}

Contrairement aux variantes de Denys Séguret et stefan.schwetschke, il permet d’insérer des symboles de séparation (espaces, tabulations, etc.) dans la chaîne de saisie, ce qui la rend plus lisible.

Exemple d'utilisation:

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");
0
John McClane

Une solution sans bibliothèque, longueur dynamique renvoyée, interprétation d'entier non signé (complément à deux)

    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 };
    }
}
0
ZMitton