web-dev-qa-db-fra.com

Lire deux octets dans un entier?

J'ai un byte[] que j'ai lu dans un fichier et je veux obtenir une int à partir de deux octets. Voici un exemple:

byte[] bytes = new byte[] {(byte)0x00, (byte)0x2F, (byte)0x01, (byte)0x10, (byte)0x6F};
int value = bytes.getInt(2,4); //This method doesn't exist

Cela devrait rendre value égal à 0x0110, ou 272 en décimal. Mais évidemment, byte[].getInt() n'existe pas. Comment puis-je accomplir cette tâche?

Le tableau ci-dessus est juste un exemple. Les valeurs réelles me sont inconnues.

23
Alexis King

Vous devriez simplement opter pour le simple:

int val = ((bytes[2] & 0xff) << 8) | (bytes[3] & 0xff);

Vous pourriez même écrire votre propre fonction d'assistance, getBytesAsWord (byte[] bytes, int start), pour vous donner les fonctionnalités si vous ne voulez pas que les calculs rediffusent votre code, mais je pense que cela serait probablement excessif.

38
paxdiablo

Essayer:

public static int getInt(byte[] arr, int off) {
  return arr[off]<<8 &0xFF00 | arr[off+1]&0xFF;
} // end of getInt

Votre question n’indique pas ce que signifient les deux arguments (2,4). 2 et 4 n'ont pas de sens dans votre exemple en tant qu'indices dans le tableau pour trouver ox01 et 0x10, j'ai supposé que vous vouliez prendre deux éléments consécutifs, chose courante, donc j'ai utilisé off et off + 1 dans ma méthode.

Vous ne pouvez pas étendre la classe byte [] en Java, vous ne pouvez donc pas utiliser une méthode bytes.getInt. J'ai donc créé une méthode statique qui utilise byte [] comme premier argument.

Le "truc" de la méthode est que vos octets sont 8 bits signés entiers et que les valeurs supérieures à 0x80 sont négatives et seraient sign étendues (par exemple 0xFFFFFF80 lorsqu'elles sont utilisées comme int). C'est pourquoi le masquage '& 0xFF' est nécessaire. le '<< 8' décale l'octet le plus significatif de 8 bits restants . Le '|' combine les deux valeurs - comme le ferait '+'. L'ordre des opérateurs est important car << a la priorité la plus élevée, suivi de & suivi de | - donc pas de parenthèses sont nécessaires.

6
Ribo

Voici un moyen simple et fiable Nice.

    ByteBuffer byteBuffer = ByteBuffer.allocateDirect(4);
    // by choosing big endian, high order bytes must be put
    // to the buffer before low order bytes
    byteBuffer.order(ByteOrder.BIG_ENDIAN);
    // since ints are 4 bytes (32 bit), you need to put all 4, so put 0
    // for the high order bytes
    byteBuffer.put((byte)0x00);
    byteBuffer.put((byte)0x00);
    byteBuffer.put((byte)0x01);
    byteBuffer.put((byte)0x10);
    byteBuffer.flip();
    int result = byteBuffer.getInt();
3
Matt

Alternativement, vous pouvez utiliser:

int val = (bytes[2] << 8) + bytes[3]
1
Weiser

La classe Google Base16 provient de Guava-14.0.1.

new BigInteger(com.google.common.io.BaseEncoding.base16().encode(bytesParam),16).longValue();
0
Koekiebox

Vous pouvez utiliser ByteBuffer. Il a la méthode getInt que vous recherchez et de nombreuses autres méthodes utiles

0
matteo rulli